kovakmedya a15a1c1c1a feat(services): customer-linked services CRUD module
Same pattern as customers. Each service belongs to one customer (FK), has
unit price (TRY), billing period (monthly/yearly/onetime), and recurring
flag.

- lib/validation/services.ts: Zod schema with TRY price coercion (accepts
  comma decimal), enum billing period, recurring boolean coercion.
- lib/appwrite/service-actions.ts: createServiceAction, updateServiceAction,
  deleteServiceAction. Same tenant guard, audit log, team-scoped row perms.
- lib/appwrite/service-queries.ts: listServices, listServicesByCustomer.
- lib/format.ts: formatTRY (Intl.NumberFormat tr-TR), formatDate/DateTime,
  BILLING_PERIOD_LABEL mapping (Aylık/Yıllık/Tek seferlik).
- /services page (server): joins services with customer names via
  in-memory map.
- ServicesClient: TanStack table with global filter (name/customer/desc),
  Repeat icon next to recurring badges, formatted TRY column.
- ServiceFormSheet: customer dropdown (disabled if no customers exist),
  unit price + billing period + recurring switch.
- DeleteServiceDialog: same destructive confirmation pattern.

Empty state on /services CTA's user back to add a customer first if none
exist.
2026-04-30 05:46:55 +03:00
S
Description
No description provided
5.2 MiB
Languages
TypeScript 99.5%
CSS 0.5%