Add full application: receipt scanning, auth, billing, and account deletion
Brings the working codebase (Next.js app, auth system, Stripe billing, Docker/deploy config, tests, docs) into version control on top of the placeholder initial commit, and adds account self-deletion (Danger Zone in Settings, password + typed-email confirmation, cascading DB cleanup, Stripe cancellation) per GDPR right-to-erasure. Excludes local build caches, node_modules, and internal agent scratch files; .gitignore hardened to keep those out going forward. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
90
drizzle/0000_noisy_magik.sql
Normal file
90
drizzle/0000_noisy_magik.sql
Normal file
@@ -0,0 +1,90 @@
|
||||
CREATE TABLE "guest_sessions" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"ip_hash" varchar(64),
|
||||
"scan_count" numeric DEFAULT '0' NOT NULL,
|
||||
"last_scan_at" timestamp,
|
||||
"expires_at" timestamp,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "licenses" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64),
|
||||
"license_key" varchar(128) NOT NULL,
|
||||
"plan" varchar(32) NOT NULL,
|
||||
"status" varchar(32) DEFAULT 'active' NOT NULL,
|
||||
"stripe_customer_id" varchar(128),
|
||||
"stripe_subscription_id" varchar(128),
|
||||
"stripe_checkout_session_id" varchar(128),
|
||||
"activated_at" timestamp DEFAULT now() NOT NULL,
|
||||
"expires_at" timestamp,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "licenses_license_key_unique" UNIQUE("license_key")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "line_items" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"receipt_id" varchar(64) NOT NULL,
|
||||
"description" text NOT NULL,
|
||||
"quantity" numeric(10, 3) DEFAULT '1' NOT NULL,
|
||||
"price" numeric(12, 2) NOT NULL,
|
||||
"unit_price" numeric(12, 2),
|
||||
"tax_rate" numeric(5, 2),
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "receipts" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"image_hash" varchar(64) NOT NULL,
|
||||
"storage_url" text,
|
||||
"merchant_name" varchar(255),
|
||||
"receipt_date" varchar(32),
|
||||
"receipt_number" varchar(128),
|
||||
"document_type" varchar(64) DEFAULT 'KASSENBON',
|
||||
"category" varchar(64) DEFAULT 'Sonstiges',
|
||||
"currency" varchar(8) DEFAULT 'EUR' NOT NULL,
|
||||
"total_amount" numeric(12, 2) NOT NULL,
|
||||
"net_amount" numeric(12, 2),
|
||||
"tax_7_amount" numeric(12, 2),
|
||||
"tax_19_amount" numeric(12, 2),
|
||||
"tip_amount" numeric(12, 2),
|
||||
"tax_breakdown_json" jsonb,
|
||||
"line_items_json" jsonb,
|
||||
"validation_json" jsonb,
|
||||
"raw_ocr_text" text,
|
||||
"payment_method" varchar(64),
|
||||
"is_math_valid" boolean DEFAULT true NOT NULL,
|
||||
"needs_review" boolean DEFAULT false NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "users" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"email" varchar(255),
|
||||
"is_guest" boolean DEFAULT true NOT NULL,
|
||||
"plan" varchar(32) DEFAULT 'free' NOT NULL,
|
||||
"stripe_customer_id" varchar(128),
|
||||
"stripe_subscription_id" varchar(128),
|
||||
"scan_count" numeric DEFAULT '0' NOT NULL,
|
||||
"expires_at" timestamp,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "licenses" ADD CONSTRAINT "licenses_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "line_items" ADD CONSTRAINT "line_items_receipt_id_receipts_id_fk" FOREIGN KEY ("receipt_id") REFERENCES "public"."receipts"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "receipts" ADD CONSTRAINT "receipts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_guest_sessions_ip" ON "guest_sessions" USING btree ("ip_hash");--> statement-breakpoint
|
||||
CREATE INDEX "idx_licenses_key" ON "licenses" USING btree ("license_key");--> statement-breakpoint
|
||||
CREATE INDEX "idx_licenses_user_id" ON "licenses" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_licenses_sub_id" ON "licenses" USING btree ("stripe_subscription_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_line_items_receipt_id" ON "line_items" USING btree ("receipt_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_receipts_user_date" ON "receipts" USING btree ("user_id","receipt_date");--> statement-breakpoint
|
||||
CREATE INDEX "idx_receipts_hash" ON "receipts" USING btree ("image_hash");--> statement-breakpoint
|
||||
CREATE INDEX "idx_receipts_duplicate_check" ON "receipts" USING btree ("user_id","merchant_name","total_amount","receipt_date");--> statement-breakpoint
|
||||
CREATE INDEX "idx_users_email" ON "users" USING btree ("email");--> statement-breakpoint
|
||||
CREATE INDEX "idx_users_guest_created" ON "users" USING btree ("is_guest","created_at");
|
||||
40
drizzle/0001_thin_blur.sql
Normal file
40
drizzle/0001_thin_blur.sql
Normal file
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE "email_verification_tokens" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"email" varchar(255) NOT NULL,
|
||||
"expires_at" timestamp NOT NULL,
|
||||
"consumed_at" timestamp,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "oauth_accounts" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"provider" varchar(32) NOT NULL,
|
||||
"provider_account_id" varchar(255) NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "sessions" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"expires_at" timestamp NOT NULL,
|
||||
"user_agent" varchar(255),
|
||||
"ip_hash" varchar(64),
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "email_key" varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "name" varchar(160);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "password_hash" varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "email_verified_at" timestamp;--> statement-breakpoint
|
||||
ALTER TABLE "email_verification_tokens" ADD CONSTRAINT "email_verification_tokens_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "oauth_accounts" ADD CONSTRAINT "oauth_accounts_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_email_verification_user_id" ON "email_verification_tokens" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_email_verification_expires_at" ON "email_verification_tokens" USING btree ("expires_at");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_oauth_provider_account" ON "oauth_accounts" USING btree ("provider","provider_account_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_oauth_accounts_user_id" ON "oauth_accounts" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_sessions_user_id" ON "sessions" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_sessions_expires_at" ON "sessions" USING btree ("expires_at");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_users_email_key" ON "users" USING btree ("email_key");
|
||||
12
drizzle/0002_giant_maria_hill.sql
Normal file
12
drizzle/0002_giant_maria_hill.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
CREATE TABLE "password_reset_tokens" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"expires_at" timestamp NOT NULL,
|
||||
"consumed_at" timestamp,
|
||||
"requested_ip_hash" varchar(64),
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "password_reset_tokens" ADD CONSTRAINT "password_reset_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 "idx_password_reset_user_id" ON "password_reset_tokens" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_password_reset_expires_at" ON "password_reset_tokens" USING btree ("expires_at");
|
||||
25
drizzle/0003_flaky_blackheart.sql
Normal file
25
drizzle/0003_flaky_blackheart.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
CREATE TABLE "launch_claims" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"position" integer NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "waitlist" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"email" varchar(255) NOT NULL,
|
||||
"name" varchar(160),
|
||||
"source" varchar(100) DEFAULT 'landing_page',
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "company" varchar(255);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "use_case" varchar(100);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "referral_source" varchar(100);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "onboarding_completed_at" timestamp;--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "launch_bonus" boolean DEFAULT false NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "launch_claims" ADD CONSTRAINT "launch_claims_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_launch_claims_user_id" ON "launch_claims" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_launch_claims_position" ON "launch_claims" USING btree ("position");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_waitlist_email" ON "waitlist" USING btree ("email");--> statement-breakpoint
|
||||
CREATE INDEX "idx_waitlist_created_at" ON "waitlist" USING btree ("created_at");
|
||||
1
drizzle/0004_add_scan_period.sql
Normal file
1
drizzle/0004_add_scan_period.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "users" ADD COLUMN "scan_period" varchar(7);--> statement-breakpoint
|
||||
15
drizzle/0005_add_security_events.sql
Normal file
15
drizzle/0005_add_security_events.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE "security_events" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"type" varchar(64) NOT NULL,
|
||||
"user_id" varchar(64),
|
||||
"email" varchar(255),
|
||||
"ip_hash" varchar(64),
|
||||
"user_agent" varchar(255),
|
||||
"metadata_json" jsonb,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "security_events" ADD CONSTRAINT "security_events_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_security_events_type_created" ON "security_events" USING btree ("type","created_at");--> statement-breakpoint
|
||||
CREATE INDEX "idx_security_events_user_created" ON "security_events" USING btree ("user_id","created_at");--> statement-breakpoint
|
||||
CREATE INDEX "idx_security_events_ip_created" ON "security_events" USING btree ("ip_hash","created_at");
|
||||
19
drizzle/0006_add_projects.sql
Normal file
19
drizzle/0006_add_projects.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE "projects" (
|
||||
"id" varchar(64) PRIMARY KEY NOT NULL,
|
||||
"user_id" varchar(64) NOT NULL,
|
||||
"name" varchar(120) NOT NULL,
|
||||
"color" varchar(16),
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "receipts" ADD COLUMN "project_id" varchar(64);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "monthly_volume" varchar(50);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "export_format" varchar(100);--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "main_pain_point" varchar(100);--> statement-breakpoint
|
||||
ALTER TABLE "projects" ADD CONSTRAINT "projects_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_projects_user_id" ON "projects" USING btree ("user_id");--> statement-breakpoint
|
||||
CREATE INDEX "idx_projects_user_created" ON "projects" USING btree ("user_id","created_at");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "uq_projects_user_name" ON "projects" USING btree ("user_id","name");--> statement-breakpoint
|
||||
ALTER TABLE "receipts" ADD CONSTRAINT "receipts_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_receipts_project" ON "receipts" USING btree ("user_id","project_id");
|
||||
2
drizzle/0007_extraction_json_and_hash.sql
Normal file
2
drizzle/0007_extraction_json_and_hash.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "receipts" ALTER COLUMN "image_hash" SET DATA TYPE varchar(128);--> statement-breakpoint
|
||||
ALTER TABLE "receipts" ADD COLUMN "extraction_json" jsonb;
|
||||
706
drizzle/meta/0000_snapshot.json
Normal file
706
drizzle/meta/0000_snapshot.json
Normal file
@@ -0,0 +1,706 @@
|
||||
{
|
||||
"id": "4d3733ee-e4ad-4775-8cd6-1d64569d7ef0",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.guest_sessions": {
|
||||
"name": "guest_sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"ip_hash": {
|
||||
"name": "ip_hash",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"scan_count": {
|
||||
"name": "scan_count",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'0'"
|
||||
},
|
||||
"last_scan_at": {
|
||||
"name": "last_scan_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_guest_sessions_ip": {
|
||||
"name": "idx_guest_sessions_ip",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "ip_hash",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.licenses": {
|
||||
"name": "licenses",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"license_key": {
|
||||
"name": "license_key",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"plan": {
|
||||
"name": "plan",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'active'"
|
||||
},
|
||||
"stripe_customer_id": {
|
||||
"name": "stripe_customer_id",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_subscription_id": {
|
||||
"name": "stripe_subscription_id",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_checkout_session_id": {
|
||||
"name": "stripe_checkout_session_id",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"activated_at": {
|
||||
"name": "activated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_licenses_key": {
|
||||
"name": "idx_licenses_key",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "license_key",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"idx_licenses_user_id": {
|
||||
"name": "idx_licenses_user_id",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "user_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"idx_licenses_sub_id": {
|
||||
"name": "idx_licenses_sub_id",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "stripe_subscription_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"licenses_user_id_users_id_fk": {
|
||||
"name": "licenses_user_id_users_id_fk",
|
||||
"tableFrom": "licenses",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "set null",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"licenses_license_key_unique": {
|
||||
"name": "licenses_license_key_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"license_key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.line_items": {
|
||||
"name": "line_items",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"receipt_id": {
|
||||
"name": "receipt_id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"quantity": {
|
||||
"name": "quantity",
|
||||
"type": "numeric(10, 3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'1'"
|
||||
},
|
||||
"price": {
|
||||
"name": "price",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"unit_price": {
|
||||
"name": "unit_price",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tax_rate": {
|
||||
"name": "tax_rate",
|
||||
"type": "numeric(5, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_line_items_receipt_id": {
|
||||
"name": "idx_line_items_receipt_id",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "receipt_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"line_items_receipt_id_receipts_id_fk": {
|
||||
"name": "line_items_receipt_id_receipts_id_fk",
|
||||
"tableFrom": "line_items",
|
||||
"tableTo": "receipts",
|
||||
"columnsFrom": [
|
||||
"receipt_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.receipts": {
|
||||
"name": "receipts",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"image_hash": {
|
||||
"name": "image_hash",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"storage_url": {
|
||||
"name": "storage_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"merchant_name": {
|
||||
"name": "merchant_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"receipt_date": {
|
||||
"name": "receipt_date",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"receipt_number": {
|
||||
"name": "receipt_number",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"document_type": {
|
||||
"name": "document_type",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'KASSENBON'"
|
||||
},
|
||||
"category": {
|
||||
"name": "category",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Sonstiges'"
|
||||
},
|
||||
"currency": {
|
||||
"name": "currency",
|
||||
"type": "varchar(8)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'EUR'"
|
||||
},
|
||||
"total_amount": {
|
||||
"name": "total_amount",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"net_amount": {
|
||||
"name": "net_amount",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tax_7_amount": {
|
||||
"name": "tax_7_amount",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tax_19_amount": {
|
||||
"name": "tax_19_amount",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tip_amount": {
|
||||
"name": "tip_amount",
|
||||
"type": "numeric(12, 2)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tax_breakdown_json": {
|
||||
"name": "tax_breakdown_json",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"line_items_json": {
|
||||
"name": "line_items_json",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"validation_json": {
|
||||
"name": "validation_json",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"raw_ocr_text": {
|
||||
"name": "raw_ocr_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"payment_method": {
|
||||
"name": "payment_method",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_math_valid": {
|
||||
"name": "is_math_valid",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"needs_review": {
|
||||
"name": "needs_review",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_receipts_user_date": {
|
||||
"name": "idx_receipts_user_date",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "user_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "receipt_date",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"idx_receipts_hash": {
|
||||
"name": "idx_receipts_hash",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "image_hash",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"idx_receipts_duplicate_check": {
|
||||
"name": "idx_receipts_duplicate_check",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "user_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "merchant_name",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "total_amount",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "receipt_date",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"receipts_user_id_users_id_fk": {
|
||||
"name": "receipts_user_id_users_id_fk",
|
||||
"tableFrom": "receipts",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(64)",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_guest": {
|
||||
"name": "is_guest",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"plan": {
|
||||
"name": "plan",
|
||||
"type": "varchar(32)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"stripe_customer_id": {
|
||||
"name": "stripe_customer_id",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_subscription_id": {
|
||||
"name": "stripe_subscription_id",
|
||||
"type": "varchar(128)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"scan_count": {
|
||||
"name": "scan_count",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'0'"
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"idx_users_email": {
|
||||
"name": "idx_users_email",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "email",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"idx_users_guest_created": {
|
||||
"name": "idx_users_guest_created",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "is_guest",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "created_at",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
1030
drizzle/meta/0001_snapshot.json
Normal file
1030
drizzle/meta/0001_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1125
drizzle/meta/0002_snapshot.json
Normal file
1125
drizzle/meta/0002_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1315
drizzle/meta/0003_snapshot.json
Normal file
1315
drizzle/meta/0003_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1461
drizzle/meta/0005_snapshot.json
Normal file
1461
drizzle/meta/0005_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1642
drizzle/meta/0006_snapshot.json
Normal file
1642
drizzle/meta/0006_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
62
drizzle/meta/_journal.json
Normal file
62
drizzle/meta/_journal.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1786900750452,
|
||||
"tag": "0000_noisy_magik",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1786950089451,
|
||||
"tag": "0001_thin_blur",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1786952172929,
|
||||
"tag": "0002_giant_maria_hill",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1786963011817,
|
||||
"tag": "0003_flaky_blackheart",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1786967682012,
|
||||
"tag": "0004_add_scan_period",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1786974929524,
|
||||
"tag": "0005_add_security_events",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1787073012101,
|
||||
"tag": "0006_add_projects",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1787130000000,
|
||||
"tag": "0007_extraction_json_and_hash",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user