PlotDirector/PlotLine/Sql/043_Phase5B_SubscriptionInfrastructure.sql
2026-06-07 10:13:16 +01:00

233 lines
7.6 KiB
Transact-SQL

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF OBJECT_ID(N'dbo.SubscriptionLevel', N'U') IS NULL
BEGIN
CREATE TABLE dbo.SubscriptionLevel
(
SubscriptionLevelID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_SubscriptionLevel PRIMARY KEY,
Name nvarchar(100) NOT NULL,
DisplayName nvarchar(100) NOT NULL,
Description nvarchar(500) NULL,
MaxBooks int NOT NULL,
MaxChaptersPerBook int NOT NULL,
MaxScenesPerBook int NOT NULL,
MaxCharactersPerProject int NOT NULL,
MaxStorageMB int NOT NULL,
MaxCollaborators int NOT NULL,
IsActive bit NOT NULL CONSTRAINT DF_SubscriptionLevel_IsActive DEFAULT 1,
SortOrder int NOT NULL,
CreatedDateUTC datetime2 NOT NULL CONSTRAINT DF_SubscriptionLevel_CreatedDateUTC DEFAULT SYSUTCDATETIME(),
ModifiedDateUTC datetime2 NOT NULL CONSTRAINT DF_SubscriptionLevel_ModifiedDateUTC DEFAULT SYSUTCDATETIME()
);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_SubscriptionLevel_Name' AND object_id = OBJECT_ID(N'dbo.SubscriptionLevel'))
CREATE UNIQUE INDEX UX_SubscriptionLevel_Name ON dbo.SubscriptionLevel(Name);
GO
IF OBJECT_ID(N'dbo.UserSubscription', N'U') IS NULL
BEGIN
CREATE TABLE dbo.UserSubscription
(
UserSubscriptionID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_UserSubscription PRIMARY KEY,
UserID int NOT NULL,
SubscriptionLevelID int NOT NULL,
StartDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_StartDateUTC DEFAULT SYSUTCDATETIME(),
EndDateUTC datetime2 NULL,
IsActive bit NOT NULL CONSTRAINT DF_UserSubscription_IsActive DEFAULT 1,
IsTrial bit NOT NULL CONSTRAINT DF_UserSubscription_IsTrial DEFAULT 0,
TrialExpiryDateUTC datetime2 NULL,
CreatedDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_CreatedDateUTC DEFAULT SYSUTCDATETIME(),
ModifiedDateUTC datetime2 NOT NULL CONSTRAINT DF_UserSubscription_ModifiedDateUTC DEFAULT SYSUTCDATETIME(),
CONSTRAINT FK_UserSubscription_AppUser FOREIGN KEY (UserID) REFERENCES dbo.AppUser(UserID),
CONSTRAINT FK_UserSubscription_SubscriptionLevel FOREIGN KEY (SubscriptionLevelID) REFERENCES dbo.SubscriptionLevel(SubscriptionLevelID)
);
END;
GO
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_UserSubscription_User_Active' AND object_id = OBJECT_ID(N'dbo.UserSubscription'))
CREATE UNIQUE INDEX UX_UserSubscription_User_Active ON dbo.UserSubscription(UserID) WHERE IsActive = 1;
GO
MERGE dbo.SubscriptionLevel AS target
USING (VALUES
(N'DraftDesk', N'Draft Desk', N'Trial and evaluation.', 2, 75, 300, 75, 100, 0, 1, 10),
(N'WritingRoom', N'Writing Room', N'Standard subscription for most authors.', 10, 150, 1000, 250, 1024, 1, 1, 20),
(N'StoryForge', N'Story Forge', N'Professional authors and co-authors.', 30, 200, 2000, 500, 5120, 3, 1, 30),
(N'AuthorStudio', N'Author Studio', N'Advanced users and writing teams.', 999999, 999999, 999999, 999999, 20480, 10, 1, 40)
) AS source
(
Name,
DisplayName,
Description,
MaxBooks,
MaxChaptersPerBook,
MaxScenesPerBook,
MaxCharactersPerProject,
MaxStorageMB,
MaxCollaborators,
IsActive,
SortOrder
)
ON target.Name = source.Name
WHEN MATCHED THEN UPDATE SET
DisplayName = source.DisplayName,
Description = source.Description,
MaxBooks = source.MaxBooks,
MaxChaptersPerBook = source.MaxChaptersPerBook,
MaxScenesPerBook = source.MaxScenesPerBook,
MaxCharactersPerProject = source.MaxCharactersPerProject,
MaxStorageMB = source.MaxStorageMB,
MaxCollaborators = source.MaxCollaborators,
IsActive = source.IsActive,
SortOrder = source.SortOrder,
ModifiedDateUTC = SYSUTCDATETIME()
WHEN NOT MATCHED THEN
INSERT
(
Name,
DisplayName,
Description,
MaxBooks,
MaxChaptersPerBook,
MaxScenesPerBook,
MaxCharactersPerProject,
MaxStorageMB,
MaxCollaborators,
IsActive,
SortOrder
)
VALUES
(
source.Name,
source.DisplayName,
source.Description,
source.MaxBooks,
source.MaxChaptersPerBook,
source.MaxScenesPerBook,
source.MaxCharactersPerProject,
source.MaxStorageMB,
source.MaxCollaborators,
source.IsActive,
source.SortOrder
);
GO
DECLARE @AuthorStudioID int;
SELECT @AuthorStudioID = SubscriptionLevelID
FROM dbo.SubscriptionLevel
WHERE Name = N'AuthorStudio';
IF @AuthorStudioID IS NOT NULL
BEGIN
INSERT INTO dbo.UserSubscription (UserID, SubscriptionLevelID, StartDateUTC, IsActive, IsTrial)
SELECT u.UserID, @AuthorStudioID, SYSUTCDATETIME(), 1, 0
FROM dbo.AppUser u
WHERE NOT EXISTS
(
SELECT 1
FROM dbo.UserSubscription us
WHERE us.UserID = u.UserID
AND us.IsActive = 1
);
END;
GO
CREATE OR ALTER PROCEDURE dbo.SubscriptionLevel_ListActive
AS
BEGIN
SET NOCOUNT ON;
SELECT SubscriptionLevelID, Name, DisplayName, Description, MaxBooks, MaxChaptersPerBook,
MaxScenesPerBook, MaxCharactersPerProject, MaxStorageMB, MaxCollaborators, IsActive,
SortOrder, CreatedDateUTC, ModifiedDateUTC
FROM dbo.SubscriptionLevel
WHERE IsActive = 1
ORDER BY SortOrder, DisplayName;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SubscriptionLevel_Get
@SubscriptionLevelID int
AS
BEGIN
SET NOCOUNT ON;
SELECT SubscriptionLevelID, Name, DisplayName, Description, MaxBooks, MaxChaptersPerBook,
MaxScenesPerBook, MaxCharactersPerProject, MaxStorageMB, MaxCollaborators, IsActive,
SortOrder, CreatedDateUTC, ModifiedDateUTC
FROM dbo.SubscriptionLevel
WHERE SubscriptionLevelID = @SubscriptionLevelID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.UserSubscription_GetCurrent
@UserID int
AS
BEGIN
SET NOCOUNT ON;
SELECT us.UserSubscriptionID, us.UserID, us.SubscriptionLevelID, us.StartDateUTC, us.EndDateUTC,
us.IsActive, us.IsTrial, us.TrialExpiryDateUTC, us.CreatedDateUTC, us.ModifiedDateUTC,
sl.Name, sl.DisplayName, sl.Description, sl.MaxBooks, sl.MaxChaptersPerBook,
sl.MaxScenesPerBook, sl.MaxCharactersPerProject, sl.MaxStorageMB, sl.MaxCollaborators,
sl.IsActive AS SubscriptionLevelIsActive, sl.SortOrder
FROM dbo.UserSubscription us
INNER JOIN dbo.SubscriptionLevel sl ON sl.SubscriptionLevelID = us.SubscriptionLevelID
WHERE us.UserID = @UserID
AND us.IsActive = 1
AND (us.EndDateUTC IS NULL OR us.EndDateUTC > SYSUTCDATETIME());
END;
GO
CREATE OR ALTER PROCEDURE dbo.UserSubscription_AssignDefaultDraftDesk
@UserID int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DraftDeskID int;
SELECT @DraftDeskID = SubscriptionLevelID
FROM dbo.SubscriptionLevel
WHERE Name = N'DraftDesk';
IF @DraftDeskID IS NULL
RETURN;
IF NOT EXISTS
(
SELECT 1
FROM dbo.UserSubscription
WHERE UserID = @UserID
AND IsActive = 1
)
BEGIN
INSERT INTO dbo.UserSubscription (UserID, SubscriptionLevelID, StartDateUTC, IsActive, IsTrial)
VALUES (@UserID, @DraftDeskID, SYSUTCDATETIME(), 1, 0);
END;
END;
GO
CREATE OR ALTER PROCEDURE dbo.User_Create
@Email nvarchar(256),
@DisplayName nvarchar(200),
@PasswordHash nvarchar(max),
@EmailConfirmed bit = 0
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.AppUser (Email, DisplayName, PasswordHash, EmailConfirmed)
VALUES (@Email, @DisplayName, @PasswordHash, @EmailConfirmed);
DECLARE @UserID int = SCOPE_IDENTITY();
EXEC dbo.UserSubscription_AssignDefaultDraftDesk @UserID = @UserID;
EXEC dbo.User_GetById @UserID = @UserID;
END;
GO