feat(shared): gate paid features from one entitlement source

Desktop, web, mobile, and the API each decided locally what a tier could do,
so a plan change could unlock a feature on one surface and not another.
Entitlement checks now live in `@d3ro/core` and are exercised by tests.

The shared theme and design-system packages also gain the tokens the new
surfaces consume, and the api-client exposes the dictionary and team types
the clients now send.
This commit is contained in:
Yun Chan 2026-09-16 23:24:18 +09:00
parent 6ba25f53b7
commit f6a29db95a
13 changed files with 576 additions and 11 deletions

View file

@ -562,6 +562,28 @@ export type Database = {
},
Partial<{ accepted_at: string | null; accepted_by: string | null }>
>
team_activities: TypedTable<
{
id: string
team_id: string
actor_id: string | null
kind: 'note' | 'member_joined' | 'member_left' | 'invite_created' | 'meeting_shared' | 'document_shared'
body: string | null
metadata: Record<string, unknown>
created_at: string
},
{
team_id: string
actor_id?: string | null
kind: 'note' | 'member_joined' | 'member_left' | 'invite_created' | 'meeting_shared' | 'document_shared'
body?: string | null
metadata?: Record<string, unknown>
},
Partial<{
body: string | null
metadata: Record<string, unknown>
}>
>
}
Views: Record<string, never>
Functions: {
@ -591,6 +613,22 @@ export type Database = {
similarity: number
}>
}
create_team_activity: {
Args: {
p_team_id: string
p_kind: string
p_body: string | null
p_metadata?: Record<string, unknown>
}
Returns: {
id: string
team_id: string
actor_id: string | null
kind: string
body: string | null
created_at: string
}
}
consume_quota: {
Args: {
p_user_id: string