Auto-derive session cookie domain; AI prompt page = formula builder hub
Session (no env needed): - SESSION_COOKIE_DOMAIN env removed. Config.SessionCookieParentDomain() derives the cookie Domain from WEB_ORIGIN + PUBLIC_API_URL, which the API already requires: sibling hosts of one parent (descrybe.io + api.descrybe.io) share the parent domain so SvelteKit SSR (/admin gate, user switching) receives the session cookie; localhost, IPs, same-host, and unrelated hosts stay host-only. Deploying the new build is the whole fix — nothing to configure. AI generation prompt page: - Each section now embeds its formula editor next to the per-language prompt instructions: Title = full title formula builder (preview, elements, separator, variable selector, custom variables), Description = description formula sections editor (type + instructions + export id, drag reorder), Meta = meta title / meta description formula fields. One Save writes categories.prompt + title_template + description_template together; Assign copies all three to the selected categories. - New $lib/categories/formula-variables.ts loads every usable field for the builder: custom variables (/api/variables), company attributes (/api/attributes — attribute_key, name, unit, example), and standard fields (/api/standard-fields). Used by both the prompt page and the title-formula page (which previously ignored attributes). Verified locally: svelte-check clean for changed files, unit tests pass, and the full save contract exercised over HTTP as the page does it (login → load variables/attributes/standard-fields → PATCH prompt + title-formula + description-formula → round-trip read), then the test category restored via repair-category-prompts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -528,3 +528,31 @@ func TestValidateProcessingPollInterval(t *testing.T) {
|
||||
t.Fatal("expected PROCESSING_POLL_INTERVAL > 0")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSessionCookieParentDomain(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct {
|
||||
name string
|
||||
web string
|
||||
api string
|
||||
want string
|
||||
}{
|
||||
{name: "prod_split", web: "https://descrybe.io", api: "https://api.descrybe.io", want: "descrybe.io"},
|
||||
{name: "prod_split_reversed", web: "https://app.descrybe.io", api: "https://descrybe.io", want: "descrybe.io"},
|
||||
{name: "sibling_subdomains", web: "https://app.descrybe.io", api: "https://api.descrybe.io", want: "descrybe.io"},
|
||||
{name: "localhost_ports", web: "http://localhost:28472", api: "http://localhost:28471", want: ""},
|
||||
{name: "loopback_ip", web: "http://127.0.0.1:28472", api: "http://127.0.0.1:28471", want: ""},
|
||||
{name: "same_host", web: "https://descrybe.io", api: "https://descrybe.io", want: ""},
|
||||
{name: "unrelated_hosts", web: "https://descrybe.io", api: "https://example.com", want: ""},
|
||||
{name: "empty_api", web: "https://descrybe.io", api: "", want: ""},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := Config{WebOrigin: tc.web, PublicAPIURL: tc.api}
|
||||
if got := c.SessionCookieParentDomain(); got != tc.want {
|
||||
t.Fatalf("web=%q api=%q got %q want %q", tc.web, tc.api, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user