Files
zpan/migrations/0010_shares.sql
T
Jasper Van de4938e75c feat: add shares schema, service layer, and lifecycle integration (#308)
- Add `shares` and `share_recipients` tables to Drizzle schema with indices
- Add migration 0010_shares.sql for shares/share_recipients tables
- Add `server/lib/password.ts` extracting scrypt hash/verify from auth.ts
  to eliminate duplicate crypto params across services
- Add `server/services/share.ts` implementing full CRUD + atomic counters:
  createShare, getShareByToken, incrementViews, incrementDownloadsAtomic
  (atomic SQL UPDATE), listSharesByCreator, revokeShare, cascadeDeleteByMatter
- Add `shared/schemas/share.ts` Zod validation schemas
- Export Share, ShareKind, ShareRecipient from shared/types
- Extend `purge.ts` to cascade-delete shares on matter hard-delete
- Add 38 integration tests and CF Workers atomic counter race tests

Agent-Profile: https://agent-kanban.dev/agents/a6bb038c4226a87f

Co-authored-by: Bob <aibob@mails.agent-kanban.dev>
2026-04-19 23:23:48 -04:00

32 lines
1.0 KiB
SQL

CREATE TABLE `shares` (
`id` text PRIMARY KEY NOT NULL,
`token` text NOT NULL,
`kind` text NOT NULL,
`matter_id` text NOT NULL,
`org_id` text NOT NULL,
`creator_id` text NOT NULL,
`password_hash` text,
`expires_at` integer,
`download_limit` integer,
`views` integer DEFAULT 0 NOT NULL,
`downloads` integer DEFAULT 0 NOT NULL,
`status` text DEFAULT 'active' NOT NULL,
`created_at` integer NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX `shares_token_unique` ON `shares` (`token`);
--> statement-breakpoint
CREATE INDEX `shares_creator_status_created_idx` ON `shares` (`creator_id`,`status`,`created_at`);
--> statement-breakpoint
CREATE TABLE `share_recipients` (
`id` text PRIMARY KEY NOT NULL,
`share_id` text NOT NULL,
`recipient_user_id` text,
`recipient_email` text,
`created_at` integer NOT NULL
);
--> statement-breakpoint
CREATE INDEX `share_recipients_share_id_idx` ON `share_recipients` (`share_id`);
--> statement-breakpoint
CREATE INDEX `share_recipients_user_id_idx` ON `share_recipients` (`recipient_user_id`);