feat: auth system, scrip scheduler, UI widgets, and new API routes
- Add session-based authentication (login page, middleware, auth context) - Add cron-like scrip scheduler for time-based conditions - Add layout builder, scrip wizard, searchable select components - Add trend chart widget for dashboards - Add notifications, attachments, queue-permissions API routes - Add seed-users script - Update schema with 10 new migrations (0008-0017) - Apply redesign: Linear-inspired dark theme, conversation-centric UI - Gitignore runtime data directory Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
12
drizzle/migrations/0008_sturdy_prism.sql
Normal file
12
drizzle/migrations/0008_sturdy_prism.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE "transaction_attachments" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"transaction_id" uuid NOT NULL,
|
||||
"filename" text NOT NULL,
|
||||
"mime_type" text DEFAULT 'application/octet-stream' NOT NULL,
|
||||
"size_bytes" integer DEFAULT 0 NOT NULL,
|
||||
"storage_path" text NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "transaction_attachments" ADD CONSTRAINT "transaction_attachments_transaction_id_transactions_id_fk" FOREIGN KEY ("transaction_id") REFERENCES "public"."transactions"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "transaction_attachments_tx_id_idx" ON "transaction_attachments" USING btree ("transaction_id");
|
||||
1
drizzle/migrations/0009_tiny_lady_vermin.sql
Normal file
1
drizzle/migrations/0009_tiny_lady_vermin.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "transaction_attachments" ALTER COLUMN "transaction_id" DROP NOT NULL;
|
||||
15
drizzle/migrations/0010_misty_morg.sql
Normal file
15
drizzle/migrations/0010_misty_morg.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE "ticket_links" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"ticket_id" integer NOT NULL,
|
||||
"target_ticket_id" integer NOT NULL,
|
||||
"link_type" text NOT NULL,
|
||||
"creator_id" uuid NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT "ticket_links_ticket_target_type_unique" UNIQUE("ticket_id","target_ticket_id","link_type")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "ticket_links" ADD CONSTRAINT "ticket_links_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "ticket_links" ADD CONSTRAINT "ticket_links_target_ticket_id_tickets_id_fk" FOREIGN KEY ("target_ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "ticket_links" ADD CONSTRAINT "ticket_links_creator_id_users_id_fk" FOREIGN KEY ("creator_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "ticket_links_ticket_id_idx" ON "ticket_links" USING btree ("ticket_id");--> statement-breakpoint
|
||||
CREATE INDEX "ticket_links_target_ticket_id_idx" ON "ticket_links" USING btree ("target_ticket_id");
|
||||
2
drizzle/migrations/0011_breezy_tyrannus.sql
Normal file
2
drizzle/migrations/0011_breezy_tyrannus.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "users" ADD COLUMN "password_hash" text;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "role" text DEFAULT 'staff' NOT NULL;
|
||||
12
drizzle/migrations/0012_living_photon.sql
Normal file
12
drizzle/migrations/0012_living_photon.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE "queue_permissions" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"queue_id" uuid NOT NULL,
|
||||
"team_id" uuid NOT NULL,
|
||||
"right_name" text NOT NULL,
|
||||
CONSTRAINT "queue_permissions_queue_team_right_unique" UNIQUE("queue_id","team_id","right_name")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "queue_permissions" ADD CONSTRAINT "queue_permissions_queue_id_queues_id_fk" FOREIGN KEY ("queue_id") REFERENCES "public"."queues"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "queue_permissions" ADD CONSTRAINT "queue_permissions_team_id_teams_id_fk" FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "queue_permissions_queue_id_idx" ON "queue_permissions" USING btree ("queue_id");--> statement-breakpoint
|
||||
CREATE INDEX "queue_permissions_team_id_idx" ON "queue_permissions" USING btree ("team_id");
|
||||
12
drizzle/migrations/0013_bored_silvermane.sql
Normal file
12
drizzle/migrations/0013_bored_silvermane.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE "user_permissions" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"queue_id" uuid NOT NULL,
|
||||
"user_id" uuid NOT NULL,
|
||||
"right_name" text NOT NULL,
|
||||
CONSTRAINT "user_permissions_queue_user_right_unique" UNIQUE("queue_id","user_id","right_name")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "user_permissions" ADD CONSTRAINT "user_permissions_queue_id_queues_id_fk" FOREIGN KEY ("queue_id") REFERENCES "public"."queues"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "user_permissions" ADD CONSTRAINT "user_permissions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "user_permissions_queue_id_idx" ON "user_permissions" USING btree ("queue_id");--> statement-breakpoint
|
||||
CREATE INDEX "user_permissions_user_id_idx" ON "user_permissions" USING btree ("user_id");
|
||||
1
drizzle/migrations/0014_cloudy_siren.sql
Normal file
1
drizzle/migrations/0014_cloudy_siren.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "transactions" ADD COLUMN "time_worked_minutes" integer DEFAULT 0;
|
||||
15
drizzle/migrations/0015_tense_patch.sql
Normal file
15
drizzle/migrations/0015_tense_patch.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE "notifications" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" uuid NOT NULL,
|
||||
"ticket_id" integer,
|
||||
"type" text NOT NULL,
|
||||
"title" text NOT NULL,
|
||||
"body" text,
|
||||
"read" boolean DEFAULT false NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "notifications" ADD CONSTRAINT "notifications_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "notifications" ADD CONSTRAINT "notifications_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "notifications_user_id_idx" ON "notifications" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "notifications_user_read_idx" ON "notifications" USING btree ("user_id","read");
|
||||
12
drizzle/migrations/0016_famous_maximus.sql
Normal file
12
drizzle/migrations/0016_famous_maximus.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE "api_tokens" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" uuid NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"token_hash" text NOT NULL,
|
||||
"last_used_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now(),
|
||||
CONSTRAINT "api_tokens_token_hash_unique" UNIQUE("token_hash")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "api_tokens" ADD CONSTRAINT "api_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "api_tokens_user_id_idx" ON "api_tokens" USING btree ("user_id");
|
||||
1
drizzle/migrations/0017_redundant_the_renegades.sql
Normal file
1
drizzle/migrations/0017_redundant_the_renegades.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "scrips" ADD COLUMN "applicable_trans_types" text;
|
||||
1418
drizzle/migrations/meta/0008_snapshot.json
Normal file
1418
drizzle/migrations/meta/0008_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1418
drizzle/migrations/meta/0009_snapshot.json
Normal file
1418
drizzle/migrations/meta/0009_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1550
drizzle/migrations/meta/0010_snapshot.json
Normal file
1550
drizzle/migrations/meta/0010_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1563
drizzle/migrations/meta/0011_snapshot.json
Normal file
1563
drizzle/migrations/meta/0011_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1669
drizzle/migrations/meta/0012_snapshot.json
Normal file
1669
drizzle/migrations/meta/0012_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1775
drizzle/migrations/meta/0013_snapshot.json
Normal file
1775
drizzle/migrations/meta/0013_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1782
drizzle/migrations/meta/0014_snapshot.json
Normal file
1782
drizzle/migrations/meta/0014_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1910
drizzle/migrations/meta/0015_snapshot.json
Normal file
1910
drizzle/migrations/meta/0015_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1999
drizzle/migrations/meta/0016_snapshot.json
Normal file
1999
drizzle/migrations/meta/0016_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2005
drizzle/migrations/meta/0017_snapshot.json
Normal file
2005
drizzle/migrations/meta/0017_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -57,6 +57,76 @@
|
||||
"when": 1781009018666,
|
||||
"tag": "0007_flimsy_roughhouse",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1781039674211,
|
||||
"tag": "0008_sturdy_prism",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1781039770418,
|
||||
"tag": "0009_tiny_lady_vermin",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1781040536590,
|
||||
"tag": "0010_misty_morg",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1781042321413,
|
||||
"tag": "0011_breezy_tyrannus",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1781043175153,
|
||||
"tag": "0012_living_photon",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1781043729230,
|
||||
"tag": "0013_bored_silvermane",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1781045611610,
|
||||
"tag": "0014_cloudy_siren",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "7",
|
||||
"when": 1781078349499,
|
||||
"tag": "0015_tense_patch",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "7",
|
||||
"when": 1781078511943,
|
||||
"tag": "0016_famous_maximus",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1781095552496,
|
||||
"tag": "0017_redundant_the_renegades",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user