Chuẩn hoá cách đọc/viết DB model Supabase (migrations + TS types + services) trong repo này.
apps/web/src/services/*-service.ts.apps/web/src/types/database.ts khi thao tác với Row/Insert/Update.apps/web/supabase/migrations/*.sqlapps/web/src/types/database.tsapps/web/src/services/blog-service.tsapps/web/src/services/docs-service.tsDatabase['public']['Tables']['blog_posts']['Row']Database['public']['Tables']['blog_posts']['Insert']Database['public']['Tables']['blog_posts']['Update']Ví dụ đang dùng trong repo:
blog_posts + profiles (author) + media (cover/og) + tags (qua blog_post_tags).tags:blog_post_tags(tag:tags(*))flattenTags trong apps/web/src/services/blog-service.ts).textSearch('search_vector', term, { type: 'websearch', config: 'simple' }).search_vector (index GIN nếu có).or(...) để match cả created_at và published_at/updated_at.applyOrDateFilter trong blog-service.ts và docs-service.ts.slugParts.join('/') và map '' -> 'index' (xem getPublicDocBySlug trong docs-service.ts).index này để tránh 2 nguồn truth.apps/web/supabase/migrations/ (DDL/RLS/indexes).apply_migrationexecute_sqlgenerate_typescript_types) để cập nhật apps/web/src/types/database.ts.apps/web/src/services/*-service.ts) và types helper nếu cần.await params/searchParams (liên quan khi query theo locale/slug).