@fonderie/billing 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/migrations/sql/001_billing.sql +38 -0
- package/dist/migrations/sql/002_billing_plan_fields.sql +5 -0
- package/dist/migrations/sql/003_drop_limits.sql +1 -0
- package/dist/migrations/sql/004_polymorphic_subscribers.sql +49 -0
- package/dist/migrations/sql/005_billing_notifications.sql +13 -0
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS fonderie_plans (
|
|
2
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
3
|
+
name TEXT NOT NULL UNIQUE,
|
|
4
|
+
seats INT,
|
|
5
|
+
trial_days INT NOT NULL DEFAULT 0,
|
|
6
|
+
monthly_amount INT,
|
|
7
|
+
monthly_price_id TEXT,
|
|
8
|
+
yearly_amount INT,
|
|
9
|
+
yearly_price_id TEXT,
|
|
10
|
+
active BOOLEAN NOT NULL DEFAULT true,
|
|
11
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS fonderie_subscriptions (
|
|
15
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
16
|
+
workspace_id UUID NOT NULL UNIQUE,
|
|
17
|
+
plan TEXT NOT NULL,
|
|
18
|
+
interval TEXT NOT NULL DEFAULT 'month',
|
|
19
|
+
status TEXT NOT NULL DEFAULT 'incomplete',
|
|
20
|
+
provider_customer_id TEXT,
|
|
21
|
+
provider_subscription_id TEXT,
|
|
22
|
+
current_period_start TIMESTAMPTZ,
|
|
23
|
+
current_period_end TIMESTAMPTZ,
|
|
24
|
+
cancel_at_period_end BOOLEAN NOT NULL DEFAULT false,
|
|
25
|
+
trial_ends_at TIMESTAMPTZ,
|
|
26
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS fonderie_usage_records (
|
|
30
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
31
|
+
workspace_id UUID NOT NULL,
|
|
32
|
+
metric TEXT NOT NULL,
|
|
33
|
+
quantity INT NOT NULL DEFAULT 1,
|
|
34
|
+
recorded_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE INDEX IF NOT EXISTS fonderie_usage_records_workspace_metric_idx
|
|
38
|
+
ON fonderie_usage_records (workspace_id, metric, recorded_at);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE fonderie_plans DROP COLUMN IF EXISTS limits;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- fonderie_subscriptions: replace workspace_id with polymorphic subscriber
|
|
2
|
+
ALTER TABLE fonderie_subscriptions
|
|
3
|
+
ADD COLUMN subscriber_type TEXT,
|
|
4
|
+
ADD COLUMN subscriber_id UUID;
|
|
5
|
+
|
|
6
|
+
UPDATE fonderie_subscriptions
|
|
7
|
+
SET subscriber_type = 'workspace',
|
|
8
|
+
subscriber_id = workspace_id;
|
|
9
|
+
|
|
10
|
+
ALTER TABLE fonderie_subscriptions
|
|
11
|
+
ALTER COLUMN subscriber_type SET NOT NULL,
|
|
12
|
+
ALTER COLUMN subscriber_id SET NOT NULL;
|
|
13
|
+
|
|
14
|
+
ALTER TABLE fonderie_subscriptions
|
|
15
|
+
DROP CONSTRAINT fonderie_subscriptions_workspace_id_key;
|
|
16
|
+
|
|
17
|
+
ALTER TABLE fonderie_subscriptions
|
|
18
|
+
DROP COLUMN workspace_id;
|
|
19
|
+
|
|
20
|
+
ALTER TABLE fonderie_subscriptions
|
|
21
|
+
ADD CONSTRAINT fonderie_subscriptions_subscriber_type_check
|
|
22
|
+
CHECK (subscriber_type IN ('user', 'workspace')),
|
|
23
|
+
ADD CONSTRAINT fonderie_subscriptions_subscriber_unique
|
|
24
|
+
UNIQUE (subscriber_type, subscriber_id);
|
|
25
|
+
|
|
26
|
+
-- fonderie_usage_records: replace workspace_id with polymorphic subscriber
|
|
27
|
+
ALTER TABLE fonderie_usage_records
|
|
28
|
+
ADD COLUMN subscriber_type TEXT,
|
|
29
|
+
ADD COLUMN subscriber_id UUID;
|
|
30
|
+
|
|
31
|
+
UPDATE fonderie_usage_records
|
|
32
|
+
SET subscriber_type = 'workspace',
|
|
33
|
+
subscriber_id = workspace_id;
|
|
34
|
+
|
|
35
|
+
ALTER TABLE fonderie_usage_records
|
|
36
|
+
ALTER COLUMN subscriber_type SET NOT NULL,
|
|
37
|
+
ALTER COLUMN subscriber_id SET NOT NULL;
|
|
38
|
+
|
|
39
|
+
ALTER TABLE fonderie_usage_records
|
|
40
|
+
DROP COLUMN workspace_id;
|
|
41
|
+
|
|
42
|
+
ALTER TABLE fonderie_usage_records
|
|
43
|
+
ADD CONSTRAINT fonderie_usage_records_subscriber_type_check
|
|
44
|
+
CHECK (subscriber_type IN ('user', 'workspace'));
|
|
45
|
+
|
|
46
|
+
DROP INDEX IF EXISTS fonderie_usage_records_workspace_metric_idx;
|
|
47
|
+
|
|
48
|
+
CREATE INDEX fonderie_usage_records_subscriber_metric_idx
|
|
49
|
+
ON fonderie_usage_records (subscriber_type, subscriber_id, metric, recorded_at);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Tracks which threshold notifications have been sent per subscriber/key/window.
|
|
2
|
+
-- Prevents duplicate emails when a subscriber hovers around a threshold.
|
|
3
|
+
CREATE TABLE IF NOT EXISTS fonderie_billing_notifications (
|
|
4
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
5
|
+
subscriber_type TEXT NOT NULL,
|
|
6
|
+
subscriber_id UUID NOT NULL,
|
|
7
|
+
policy_key TEXT NOT NULL,
|
|
8
|
+
notification TEXT NOT NULL, -- 'warning' | 'reached' | 'blocked'
|
|
9
|
+
window_key TEXT NOT NULL, -- e.g. '2026-05-13' for a 1-day window
|
|
10
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
11
|
+
CONSTRAINT fonderie_billing_notifications_unique
|
|
12
|
+
UNIQUE (subscriber_type, subscriber_id, policy_key, notification, window_key)
|
|
13
|
+
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonderie/billing",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "SaaS billing in one module — config-driven plan catalogue, Stripe subscriptions, polymorphic user and workspace billing surfaces, usage metering, and webhook handling.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fonderie-js",
|