web server
This commit is contained in:
291
web-server/database/02_schema.sql
Normal file
291
web-server/database/02_schema.sql
Normal file
@@ -0,0 +1,291 @@
|
||||
USE [RobotInstaller];
|
||||
GO
|
||||
|
||||
SET ANSI_NULLS ON;
|
||||
SET QUOTED_IDENTIFIER ON;
|
||||
GO
|
||||
|
||||
IF OBJECT_ID(N'dbo.ApplicationPackages', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.PackageVersions', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.Applications', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.Packages', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.EmailConfirmationTokens', N'U') IS NOT NULL
|
||||
OR OBJECT_ID(N'dbo.Users', N'U') IS NOT NULL
|
||||
BEGIN
|
||||
THROW 50001, 'Schema tables already exist. Review, drop, or migrate existing tables before running 02_schema.sql.', 1;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.Users
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_Users PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_Users_Id DEFAULT NEWSEQUENTIALID(),
|
||||
Username NVARCHAR(100) NOT NULL,
|
||||
Email NVARCHAR(255) NOT NULL,
|
||||
PasswordHash NVARCHAR(500) NOT NULL,
|
||||
FullName NVARCHAR(200) NULL,
|
||||
Role NVARCHAR(50) NOT NULL
|
||||
CONSTRAINT DF_Users_Role DEFAULT N'User',
|
||||
IsActive BIT NOT NULL
|
||||
CONSTRAINT DF_Users_IsActive DEFAULT 1,
|
||||
CreatedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_Users_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
UpdatedAt DATETIME2(3) NULL,
|
||||
CONSTRAINT CK_Users_Role CHECK (Role IN (N'Admin', N'User')),
|
||||
CONSTRAINT CK_Users_Username_NotBlank CHECK (LEN(LTRIM(RTRIM(Username))) > 0),
|
||||
CONSTRAINT CK_Users_Email_NotBlank CHECK (LEN(LTRIM(RTRIM(Email))) > 0)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.EmailConfirmationTokens
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_EmailConfirmationTokens PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_EmailConfirmationTokens_Id DEFAULT NEWSEQUENTIALID(),
|
||||
UserId UNIQUEIDENTIFIER NOT NULL,
|
||||
TokenHash CHAR(64) NOT NULL,
|
||||
ExpiresAt DATETIME2(3) NOT NULL,
|
||||
ConfirmedAt DATETIME2(3) NULL,
|
||||
CreatedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_EmailConfirmationTokens_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
CONSTRAINT FK_EmailConfirmationTokens_User
|
||||
FOREIGN KEY (UserId) REFERENCES dbo.Users(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.Packages
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_Packages PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_Packages_Id DEFAULT NEWSEQUENTIALID(),
|
||||
PackageCode NVARCHAR(100) NOT NULL,
|
||||
PackageName NVARCHAR(200) NOT NULL,
|
||||
PackageType NVARCHAR(20) NOT NULL,
|
||||
Description NVARCHAR(MAX) NULL,
|
||||
CreatedByUserId UNIQUEIDENTIFIER NOT NULL,
|
||||
CreatedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_Packages_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
UpdatedAt DATETIME2(3) NULL,
|
||||
IsActive BIT NOT NULL
|
||||
CONSTRAINT DF_Packages_IsActive DEFAULT 1,
|
||||
CONSTRAINT FK_Packages_CreatedByUser
|
||||
FOREIGN KEY (CreatedByUserId) REFERENCES dbo.Users(Id),
|
||||
CONSTRAINT CK_Packages_PackageType CHECK (PackageType IN (N'deb', N'docker')),
|
||||
CONSTRAINT CK_Packages_PackageCode_NotBlank CHECK (LEN(LTRIM(RTRIM(PackageCode))) > 0),
|
||||
CONSTRAINT CK_Packages_PackageName_NotBlank CHECK (LEN(LTRIM(RTRIM(PackageName))) > 0)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.PackageVersions
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_PackageVersions PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_PackageVersions_Id DEFAULT NEWSEQUENTIALID(),
|
||||
PackageId UNIQUEIDENTIFIER NOT NULL,
|
||||
Version NVARCHAR(50) NOT NULL,
|
||||
FilePath NVARCHAR(1000) NULL,
|
||||
DockerImage NVARCHAR(500) NULL,
|
||||
FileChecksumSha256 CHAR(64) NULL,
|
||||
FileSizeBytes BIGINT NULL,
|
||||
ChangeLog NVARCHAR(MAX) NULL,
|
||||
ReleaseDate DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_PackageVersions_ReleaseDate DEFAULT SYSUTCDATETIME(),
|
||||
UploadedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_PackageVersions_UploadedAt DEFAULT SYSUTCDATETIME(),
|
||||
IsLatest BIT NOT NULL
|
||||
CONSTRAINT DF_PackageVersions_IsLatest DEFAULT 0,
|
||||
IsDeprecated BIT NOT NULL
|
||||
CONSTRAINT DF_PackageVersions_IsDeprecated DEFAULT 0,
|
||||
CONSTRAINT FK_PackageVersions_Package
|
||||
FOREIGN KEY (PackageId) REFERENCES dbo.Packages(Id) ON DELETE CASCADE,
|
||||
CONSTRAINT CK_PackageVersions_Version_NotBlank CHECK (LEN(LTRIM(RTRIM(Version))) > 0),
|
||||
CONSTRAINT CK_PackageVersions_FileSizeBytes CHECK (FileSizeBytes IS NULL OR FileSizeBytes >= 0),
|
||||
CONSTRAINT CK_PackageVersions_FileChecksumSha256 CHECK (
|
||||
FileChecksumSha256 IS NULL
|
||||
OR FileChecksumSha256 NOT LIKE '%[^0-9A-Fa-f]%'
|
||||
)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.Applications
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_Applications PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_Applications_Id DEFAULT NEWSEQUENTIALID(),
|
||||
AppCode NVARCHAR(100) NOT NULL,
|
||||
AppName NVARCHAR(200) NOT NULL,
|
||||
AppVersion NVARCHAR(50) NOT NULL
|
||||
CONSTRAINT DF_Applications_AppVersion DEFAULT N'1.0.0',
|
||||
Description NVARCHAR(MAX) NULL,
|
||||
CreatedByUserId UNIQUEIDENTIFIER NOT NULL,
|
||||
CreatedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_Applications_CreatedAt DEFAULT SYSUTCDATETIME(),
|
||||
UpdatedAt DATETIME2(3) NULL,
|
||||
Status NVARCHAR(50) NOT NULL
|
||||
CONSTRAINT DF_Applications_Status DEFAULT N'Draft',
|
||||
Notes NVARCHAR(500) NULL,
|
||||
CONSTRAINT FK_Applications_CreatedByUser
|
||||
FOREIGN KEY (CreatedByUserId) REFERENCES dbo.Users(Id),
|
||||
CONSTRAINT CK_Applications_Status CHECK (Status IN (N'Draft', N'Released', N'Archived')),
|
||||
CONSTRAINT CK_Applications_AppCode_NotBlank CHECK (LEN(LTRIM(RTRIM(AppCode))) > 0),
|
||||
CONSTRAINT CK_Applications_AppName_NotBlank CHECK (LEN(LTRIM(RTRIM(AppName))) > 0),
|
||||
CONSTRAINT CK_Applications_AppVersion_NotBlank CHECK (LEN(LTRIM(RTRIM(AppVersion))) > 0)
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE TABLE dbo.ApplicationPackages
|
||||
(
|
||||
Id UNIQUEIDENTIFIER NOT NULL
|
||||
CONSTRAINT PK_ApplicationPackages PRIMARY KEY CLUSTERED
|
||||
CONSTRAINT DF_ApplicationPackages_Id DEFAULT NEWSEQUENTIALID(),
|
||||
ApplicationId UNIQUEIDENTIFIER NOT NULL,
|
||||
PackageId UNIQUEIDENTIFIER NOT NULL,
|
||||
SelectedVersionId UNIQUEIDENTIFIER NULL,
|
||||
AddedAt DATETIME2(3) NOT NULL
|
||||
CONSTRAINT DF_ApplicationPackages_AddedAt DEFAULT SYSUTCDATETIME(),
|
||||
Notes NVARCHAR(500) NULL,
|
||||
CONSTRAINT FK_ApplicationPackages_Application
|
||||
FOREIGN KEY (ApplicationId) REFERENCES dbo.Applications(Id) ON DELETE CASCADE,
|
||||
CONSTRAINT FK_ApplicationPackages_Package
|
||||
FOREIGN KEY (PackageId) REFERENCES dbo.Packages(Id) ON DELETE CASCADE
|
||||
);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_Users_Username ON dbo.Users(Username);
|
||||
CREATE UNIQUE INDEX UX_Users_Email ON dbo.Users(Email);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_EmailConfirmationTokens_TokenHash
|
||||
ON dbo.EmailConfirmationTokens(TokenHash);
|
||||
|
||||
CREATE INDEX IX_EmailConfirmationTokens_UserId
|
||||
ON dbo.EmailConfirmationTokens(UserId);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_Packages_PackageCode ON dbo.Packages(PackageCode);
|
||||
CREATE INDEX IX_Packages_CreatedByUserId ON dbo.Packages(CreatedByUserId);
|
||||
CREATE INDEX IX_Packages_PackageType ON dbo.Packages(PackageType);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_PackageVersions_PackageId_Version
|
||||
ON dbo.PackageVersions(PackageId, Version);
|
||||
|
||||
CREATE UNIQUE INDEX UX_PackageVersions_Id_PackageId
|
||||
ON dbo.PackageVersions(Id, PackageId);
|
||||
|
||||
CREATE UNIQUE INDEX UX_PackageVersions_OneLatestPerPackage
|
||||
ON dbo.PackageVersions(PackageId)
|
||||
WHERE IsLatest = 1;
|
||||
|
||||
CREATE INDEX IX_PackageVersions_PackageId_ReleaseDate
|
||||
ON dbo.PackageVersions(PackageId, ReleaseDate DESC);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_Applications_AppCode
|
||||
ON dbo.Applications(AppCode);
|
||||
|
||||
CREATE INDEX IX_Applications_CreatedByUserId ON dbo.Applications(CreatedByUserId);
|
||||
CREATE INDEX IX_Applications_Status ON dbo.Applications(Status);
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX UX_ApplicationPackages_ApplicationId_PackageId
|
||||
ON dbo.ApplicationPackages(ApplicationId, PackageId);
|
||||
|
||||
CREATE INDEX IX_ApplicationPackages_PackageId
|
||||
ON dbo.ApplicationPackages(PackageId);
|
||||
|
||||
CREATE INDEX IX_ApplicationPackages_SelectedVersionId
|
||||
ON dbo.ApplicationPackages(SelectedVersionId);
|
||||
GO
|
||||
|
||||
ALTER TABLE dbo.ApplicationPackages
|
||||
ADD CONSTRAINT FK_ApplicationPackages_SelectedVersionBelongsToPackage
|
||||
FOREIGN KEY (SelectedVersionId, PackageId)
|
||||
REFERENCES dbo.PackageVersions(Id, PackageId);
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE dbo.SetLatestPackageVersion
|
||||
@PackageVersionId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
DECLARE @PackageId UNIQUEIDENTIFIER;
|
||||
|
||||
SELECT @PackageId = PackageId
|
||||
FROM dbo.PackageVersions
|
||||
WHERE Id = @PackageVersionId;
|
||||
|
||||
IF @PackageId IS NULL
|
||||
BEGIN
|
||||
THROW 50002, 'Package version does not exist.', 1;
|
||||
END;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
UPDATE dbo.PackageVersions
|
||||
SET IsLatest = 0
|
||||
WHERE PackageId = @PackageId;
|
||||
|
||||
UPDATE dbo.PackageVersions
|
||||
SET IsLatest = 1,
|
||||
IsDeprecated = 0
|
||||
WHERE Id = @PackageVersionId;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
END;
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE dbo.DeletePackageVersion
|
||||
@PackageVersionId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SET XACT_ABORT ON;
|
||||
|
||||
DECLARE @PackageId UNIQUEIDENTIFIER;
|
||||
DECLARE @WasLatest BIT;
|
||||
|
||||
SELECT
|
||||
@PackageId = PackageId,
|
||||
@WasLatest = IsLatest
|
||||
FROM dbo.PackageVersions
|
||||
WHERE Id = @PackageVersionId;
|
||||
|
||||
IF @PackageId IS NULL
|
||||
BEGIN
|
||||
THROW 50003, 'Package version does not exist.', 1;
|
||||
END;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
DELETE FROM dbo.ApplicationPackages
|
||||
WHERE SelectedVersionId = @PackageVersionId;
|
||||
|
||||
DELETE FROM dbo.PackageVersions
|
||||
WHERE Id = @PackageVersionId;
|
||||
|
||||
IF @WasLatest = 1
|
||||
BEGIN
|
||||
DECLARE @NextLatestId UNIQUEIDENTIFIER;
|
||||
|
||||
SELECT TOP (1) @NextLatestId = Id
|
||||
FROM dbo.PackageVersions
|
||||
WHERE PackageId = @PackageId
|
||||
AND IsDeprecated = 0
|
||||
ORDER BY ReleaseDate DESC, UploadedAt DESC;
|
||||
|
||||
IF @NextLatestId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC dbo.SetLatestPackageVersion @NextLatestId;
|
||||
END;
|
||||
END;
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
END;
|
||||
GO
|
||||
|
||||
PRINT N'RobotInstaller schema was created successfully.';
|
||||
GO
|
||||
Reference in New Issue
Block a user