brand
무료Apply this site's visual identity — colours, type, logo files and fixed brand strings. Use for any page, component, social asset or document that should look like the site.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when writing or applying a migration in site-os, adding a table or column, storing files, or when a migration fails with "must be owner of table" — covers the apply procedure, the postgres-ownership rule, money/rate units, and where files belong.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Postgres, self-hosted Supabase on your-vps, under Coolify.
There is no migration runner. Migrations are applied by hand, in order, and nothing records that they were. Check first, never assume:
SELECT to_regclass('public.<a table it creates>') IS NOT NULL;
./scripts/coolify-tunnel.sh # if not already up
scp supabase/migrations/0NN_x.sql your-vps:/tmp/
ssh your-vps "sudo docker cp /tmp/0NN_x.sql supabase-db-<service-uuid>:/tmp/ \
&& sudo docker exec supabase-db-<service-uuid> \
psql -U postgres -d postgres -v ON_ERROR_STOP=1 --single-transaction -f /tmp/0NN_x.sql"
ON_ERROR_STOP=1 --single-transaction is not optional. Without it psql
continues past an error and leaves the migration half-applied — worse than a
clean failure.
Applying to production touches live data. Ask first unless the operator has already said to apply it.
must be owner of table — do not switch rolesEvery table in public is owned by postgres. If a migration fails with
must be owner of table X, something created X as another role. Fix the owner:
ALTER TABLE public.X OWNER TO postgres;
Do not reach for -U supabase_admin to get past it. That makes the one
migration work and deepens the split, so the next one fails somewhere else.
This exact situation happened on 2026-09-16 (migration 033); migration 034
normalised all 29 tables. Ownership decides only who may run DDL — not RLS,
policies, grants, or application behaviour. supabase_admin legitimately owns
the internal schemas (auth, storage, realtime).
Invariant, should return nothing:
SELECT tablename, tableowner FROM pg_tables
WHERE schemaname = 'public' AND tableowner <> 'postgres';
price_paise, amount_paise, tax_base_paise.gst_rate_bp, discount_bp. 1800 = 18%.src/lib/gst.ts and src/lib/pricing.ts
both have property tests asserting that.| What | Where | Ceiling |
|---|---|---|
| Invoice PDFs | invoice_archive | ~4 KB each |
| Guides, blueprints, prompt libraries | product_assets | 25 MB, CHECK-enforced |
| Installers, video, anything large | not the database | GitHub release or external URL |
Postgres over object storage for small durable files: it is already in the backup, it moves with the database, and there is no split-brain between a row and a bucket. Cloudflare R2 is not enabled on the account (checked 2026-09-16). The CHECK is what makes the boundary loud instead of a judgement call.
CHECK the invariant, and mirror it in the server action. The constraint
is the guarantee; the mirror is so the admin sees a message on the field
rather than a database error they cannot act on.products.fulfilment_kind + fulfilment_config: a new delivery method is a
new kind and a handler, not a migration.invoice_archive has a
trigger refusing UPDATE — correcting an invoice is a credit note, not an
edit.mutate() (admin/lib/db.ts), which runs the
change and perform_action() in one transaction, so the capability check and
the audit row cannot come apart.REVOKE ALL ... FROM anon, authenticated and no policy. Remember
public.app_config grants SELECT to anon — never put a secret there.tsc cannot see inside a SQL string. A placeholder with no parameter compiles
and fails at runtime — this has already happened twice here. After editing a
parameterised statement, count them:
# highest $n in the SQL must equal the number of params passed
Then run pnpm build && pnpm test && pnpm env:check.
docs/OPS.md §3 (which store holds which value) and §3.5 (this, in full).[[site-mcp]] — the MCP write path for content and products.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Apply this site's visual identity — colours, type, logo files and fixed brand strings. Use for any page, component, social asset or document that should look like the site.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use FIRST when someone asks for a new feature or a change to an existing one — before any schema, code or test. Works out what is actually being asked for, whether to build it or integrate a third party (Trustpilot, Stripe, Calendly and the like), where the data lives, who may do what, and what happens when the vendor is down. Produces a decision, then hands to feature-schema.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when a new feature needs a table, column or capability — evolving the schema so the new thing joins the permission, audit and RLS contract instead of sitting outside it. Covers the DDL/DML split, the resource/capability wiring, and the self-verifying migration.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use after building a feature — explore it in a real browser to find what nobody predicted, then turn each finding into a deterministic test that guards it forever. Covers the agentic pass, what to generate vs hand-write, and how to skip honestly when a capability is missing.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Publishing content or deploying site-os — what caches exist, what refreshes them, and how to prove a change is actually live. Use when publishing a post or product, launching a page, deploying, or when someone says a change "isn't showing".
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Handling secrets, keys and credentials for site-os — reading vigyan-secrets.md safely, moving keys into app_secrets, rotating, and responding to an exposure. Use whenever a task touches a key, token, password, .env file, app_secrets, encryption, or the secrets document.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.