web server

This commit is contained in:
2026-05-20 14:10:25 +07:00
parent 5ade939ff9
commit 190d2418da
30 changed files with 8917 additions and 0 deletions

View 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