api: spam check settings, lookups and cache
SD1 (14 §9): the spam/lookups tables and calls columns, the IPQualityScore and FTC lookups with the cache, the spam settings with write-only keys, the provider Test routes and Settings → Spam check.
This commit is contained in:
1 parent
a3dfcb6b14
commit
6f87d6f663
22 files changed
+5907
-23
No files matched your search
@@ -0,0 +1,25 @@
|
||||
CREATE TABLE "ftc_complaints" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"number" text NOT NULL,
|
||||
"reported_at" timestamp with time zone NOT NULL,
|
||||
"subject" text,
|
||||
"robocall" boolean,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "spam_lookups" (
|
||||
"number" text PRIMARY KEY NOT NULL,
|
||||
"provider" text NOT NULL,
|
||||
"risk" text NOT NULL,
|
||||
"info" jsonb NOT NULL,
|
||||
"expires_at" timestamp with time zone NOT NULL,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "spam_lookups_risk_check" CHECK ("spam_lookups"."risk" in ('low', 'medium', 'high'))
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "calls" ADD COLUMN "spam_risk" text;--> statement-breakpoint
|
||||
ALTER TABLE "calls" ADD COLUMN "spam_info" jsonb;--> statement-breakpoint
|
||||
CREATE INDEX "ftc_complaints_number_index" ON "ftc_complaints" USING btree ("number");--> statement-breakpoint
|
||||
CREATE INDEX "ftc_complaints_reported_at_index" ON "ftc_complaints" USING btree ("reported_at");--> statement-breakpoint
|
||||
CREATE INDEX "spam_lookups_expires_at_index" ON "spam_lookups" USING btree ("expires_at");
|
||||
File diff suppressed because it is too large.
Load diff
@@ -99,6 +99,13 @@
|
||||
"when": 1793052019332,
|
||||
"tag": "0013_mobile_devices",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1793127210386,
|
||||
"tag": "0014_spam_check",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -630,11 +630,46 @@ export const calls = pgTable(
|
||||
answeredByExtensionId: uuid().references(() => extensions.id, { onDelete: 'set null' }),
|
||||
talkSeconds: integer().notNull().default(0),
|
||||
recordingId: uuid().references(() => recordings.id, { onDelete: 'set null' }),
|
||||
/** The spam check of an incoming call's number (14 §6); null = not checked. */
|
||||
spamRisk: text(),
|
||||
spamInfo: jsonb(),
|
||||
...timestamps,
|
||||
},
|
||||
(t) => [index().on(t.startedAt.desc())],
|
||||
);
|
||||
|
||||
// ───────────── spam check (14 §7) ─────────────
|
||||
/** IPQualityScore answers, so a caller who rings again costs no credit (14 §4). */
|
||||
export const spamLookups = pgTable(
|
||||
'spam_lookups',
|
||||
{
|
||||
number: text().primaryKey(),
|
||||
provider: text().notNull(),
|
||||
risk: text().notNull(),
|
||||
info: jsonb().notNull(),
|
||||
expiresAt: tstz().notNull(),
|
||||
...timestamps,
|
||||
},
|
||||
(t) => [
|
||||
index().on(t.expiresAt),
|
||||
check('spam_lookups_risk_check', sql`${t.risk} in ('low', 'medium', 'high')`),
|
||||
],
|
||||
);
|
||||
|
||||
/** The local copy of the FTC's Do Not Call complaints (14 §2.2). */
|
||||
export const ftcComplaints = pgTable(
|
||||
'ftc_complaints',
|
||||
{
|
||||
id: text().primaryKey(),
|
||||
number: text().notNull(),
|
||||
reportedAt: tstz().notNull(),
|
||||
subject: text(),
|
||||
robocall: boolean(),
|
||||
createdAt: createdAt(),
|
||||
},
|
||||
(t) => [index().on(t.number), index().on(t.reportedAt)],
|
||||
);
|
||||
|
||||
export const callExtensions = pgTable(
|
||||
'call_extensions',
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user