diff --git a/deployment/nginx.conf b/deployment/nginx.conf index fa4630a8..03aa2417 100644 --- a/deployment/nginx.conf +++ b/deployment/nginx.conf @@ -22,7 +22,7 @@ server { # API proxy to backend location /api/ { - proxy_pass http://backend:3000/; + proxy_pass http://backend:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; diff --git a/deployment/serpentrace-backend.tar b/deployment/serpentrace-backend.tar new file mode 100644 index 00000000..b0bb0e6b Binary files /dev/null and b/deployment/serpentrace-backend.tar differ diff --git a/deployment/serpentrace-frontend.tar b/deployment/serpentrace-frontend.tar new file mode 100644 index 00000000..07de2870 Binary files /dev/null and b/deployment/serpentrace-frontend.tar differ diff --git a/deployment/sql_schema_only.sql b/deployment/sql_schema_only.sql index e36d9e25..95f884ce 100644 --- a/deployment/sql_schema_only.sql +++ b/deployment/sql_schema_only.sql @@ -1,236 +1,180 @@ --- SerpentRace Database Schema --- Generated from TypeORM Entity Aggregates --- This file creates the complete database schema without initial data - --- Enable UUID extension -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - --- Create Users table -CREATE TABLE "Users" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "orgid" UUID NULL, - "username" VARCHAR(100) UNIQUE NOT NULL, - "password" VARCHAR(255) NOT NULL, - "email" VARCHAR(255) UNIQUE NOT NULL, - "fname" VARCHAR(100) NOT NULL, - "lname" VARCHAR(100) NOT NULL, - "token" VARCHAR(255) NULL, - "TokenExpires" TIMESTAMP NULL, - "phone" VARCHAR(20) NULL, - "state" INTEGER NOT NULL DEFAULT 0, - "regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "Orglogindate" TIMESTAMP NULL -); - --- Create Organizations table -CREATE TABLE "Organizations" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "name" VARCHAR(255) NOT NULL, - "contactfname" VARCHAR(100) NOT NULL, - "contactlname" VARCHAR(100) NOT NULL, - "contactphone" VARCHAR(20) NOT NULL, - "contactemail" VARCHAR(255) NOT NULL, - "state" INTEGER NOT NULL DEFAULT 0, - "regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "url" VARCHAR(500) NULL, - "userinorg" INTEGER NOT NULL DEFAULT 0, - "maxOrganizationalDecks" INTEGER NULL -); - --- Create Decks table -CREATE TABLE "Decks" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "name" VARCHAR(255) NOT NULL, - "type" INTEGER NOT NULL, - "user_id" UUID NOT NULL, - "creation_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "cards" JSONB NOT NULL DEFAULT '[]', - "played_number" INTEGER NOT NULL DEFAULT 0, - "ctype" INTEGER NOT NULL DEFAULT 0, - "update_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "state" INTEGER NOT NULL DEFAULT 0, - "organization_id" UUID NULL -); - --- Create Chats table -CREATE TABLE "Chats" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "type" VARCHAR(50) NOT NULL DEFAULT 'direct', - "name" VARCHAR(255) NULL, - "gameId" UUID NULL, - "createdBy" UUID NULL, - "users" UUID[] NOT NULL, - "messages" JSONB NOT NULL DEFAULT '[]', - "lastActivity" TIMESTAMP NULL, - "createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "state" INTEGER NOT NULL DEFAULT 0, - "archiveDate" TIMESTAMP NULL -); - --- Create Contacts table -CREATE TABLE "Contacts" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "name" VARCHAR(255) NOT NULL, - "email" VARCHAR(255) NOT NULL, - "userid" UUID NULL, - "type" INTEGER NOT NULL, - "txt" TEXT NOT NULL, - "state" INTEGER NOT NULL DEFAULT 0, - "createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "adminResponse" TEXT NULL, - "responseDate" TIMESTAMP NULL, - "respondedBy" UUID NULL -); - --- Create Games table -CREATE TABLE "Games" ( - "id" UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - "gamecode" VARCHAR(10) UNIQUE NOT NULL, - "maxplayers" INTEGER NOT NULL, - "logintype" INTEGER NOT NULL DEFAULT 0, - "state" INTEGER NOT NULL DEFAULT 0, - "playerids" UUID[] NOT NULL DEFAULT '{}', - "decks" JSONB NOT NULL DEFAULT '[]', - "boardsize" INTEGER NOT NULL DEFAULT 50, - "createDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "finishDate" TIMESTAMP NULL, - "winnerid" UUID NULL, - "createdBy" UUID NOT NULL, - "organizationid" UUID NULL -); - --- Add Foreign Key Constraints -ALTER TABLE "Users" -ADD CONSTRAINT "FK_Users_Organizations" -FOREIGN KEY ("orgid") REFERENCES "Organizations"("id") ON DELETE SET NULL; - -ALTER TABLE "Decks" -ADD CONSTRAINT "FK_Decks_Users" -FOREIGN KEY ("user_id") REFERENCES "Users"("id") ON DELETE CASCADE; - -ALTER TABLE "Decks" -ADD CONSTRAINT "FK_Decks_Organizations" -FOREIGN KEY ("organization_id") REFERENCES "Organizations"("id") ON DELETE SET NULL; - -ALTER TABLE "Contacts" -ADD CONSTRAINT "FK_Contacts_Users" -FOREIGN KEY ("userid") REFERENCES "Users"("id") ON DELETE SET NULL; - -ALTER TABLE "Contacts" -ADD CONSTRAINT "FK_Contacts_RespondedBy" -FOREIGN KEY ("respondedBy") REFERENCES "Users"("id") ON DELETE SET NULL; - -ALTER TABLE "Chats" -ADD CONSTRAINT "FK_Chats_CreatedBy" -FOREIGN KEY ("createdBy") REFERENCES "Users"("id") ON DELETE SET NULL; - -ALTER TABLE "Chats" -ADD CONSTRAINT "FK_Chats_Games" -FOREIGN KEY ("gameId") REFERENCES "Games"("id") ON DELETE SET NULL; - -ALTER TABLE "Games" -ADD CONSTRAINT "FK_Games_CreatedBy" -FOREIGN KEY ("createdBy") REFERENCES "Users"("id") ON DELETE CASCADE; - -ALTER TABLE "Games" -ADD CONSTRAINT "FK_Games_Organizations" -FOREIGN KEY ("organizationid") REFERENCES "Organizations"("id") ON DELETE SET NULL; - -ALTER TABLE "Games" -ADD CONSTRAINT "FK_Games_Winner" -FOREIGN KEY ("winnerid") REFERENCES "Users"("id") ON DELETE SET NULL; - --- Create Indexes for Performance -CREATE INDEX "IDX_Users_Username" ON "Users" ("username"); -CREATE INDEX "IDX_Users_Email" ON "Users" ("email"); -CREATE INDEX "IDX_Users_OrgId" ON "Users" ("orgid"); -CREATE INDEX "IDX_Users_State" ON "Users" ("state"); - -CREATE INDEX "IDX_Organizations_Name" ON "Organizations" ("name"); -CREATE INDEX "IDX_Organizations_State" ON "Organizations" ("state"); - -CREATE INDEX "IDX_Decks_UserId" ON "Decks" ("user_id"); -CREATE INDEX "IDX_Decks_Type" ON "Decks" ("type"); -CREATE INDEX "IDX_Decks_CType" ON "Decks" ("ctype"); -CREATE INDEX "IDX_Decks_State" ON "Decks" ("state"); -CREATE INDEX "IDX_Decks_OrganizationId" ON "Decks" ("organization_id"); - -CREATE INDEX "IDX_Chats_Type" ON "Chats" ("type"); -CREATE INDEX "IDX_Chats_State" ON "Chats" ("state"); -CREATE INDEX "IDX_Chats_GameId" ON "Chats" ("gameId"); -CREATE INDEX "IDX_Chats_CreatedBy" ON "Chats" ("createdBy"); - -CREATE INDEX "IDX_Contacts_Type" ON "Contacts" ("type"); -CREATE INDEX "IDX_Contacts_State" ON "Contacts" ("state"); -CREATE INDEX "IDX_Contacts_UserId" ON "Contacts" ("userid"); - -CREATE INDEX "IDX_Games_GameCode" ON "Games" ("gamecode"); -CREATE INDEX "IDX_Games_State" ON "Games" ("state"); -CREATE INDEX "IDX_Games_CreatedBy" ON "Games" ("createdBy"); -CREATE INDEX "IDX_Games_OrganizationId" ON "Games" ("organizationid"); - --- Create update trigger for updatedate columns -CREATE OR REPLACE FUNCTION update_updatedate_column() -RETURNS TRIGGER AS $$ -BEGIN - NEW.updatedate = CURRENT_TIMESTAMP; - RETURN NEW; -END; -$$ language 'plpgsql'; - --- Apply update triggers -CREATE TRIGGER update_users_updatedate - BEFORE UPDATE ON "Users" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_organizations_updatedate - BEFORE UPDATE ON "Organizations" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_decks_updatedate - BEFORE UPDATE ON "Decks" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_chats_updatedate - BEFORE UPDATE ON "Chats" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_contacts_updatedate - BEFORE UPDATE ON "Contacts" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_games_updatedate - BEFORE UPDATE ON "Games" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - --- Comments for documentation -COMMENT ON TABLE "Users" IS 'User accounts with authentication and profile information'; -COMMENT ON TABLE "Organizations" IS 'Organizations that can have multiple users and premium features'; -COMMENT ON TABLE "Decks" IS 'Card decks for the game, can be public, private, or organizational'; -COMMENT ON TABLE "Chats" IS 'Chat system supporting direct messages, groups, and game chats'; -COMMENT ON TABLE "Contacts" IS 'Contact form submissions and support tickets'; -COMMENT ON TABLE "Games" IS 'Game sessions with players, decks, and game state'; - --- Enum value comments -COMMENT ON COLUMN "Users"."state" IS '0=REGISTERED_NOT_VERIFIED, 1=VERIFIED_REGULAR, 2=VERIFIED_PREMIUM, 3=SOFT_DELETE, 4=DEACTIVATED, 5=ADMIN'; -COMMENT ON COLUMN "Organizations"."state" IS '0=REGISTERED, 1=ACTIVE, 2=SOFT_DELETE'; -COMMENT ON COLUMN "Decks"."type" IS '0=LUCK, 1=JOKER, 2=QUESTION'; -COMMENT ON COLUMN "Decks"."ctype" IS '0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION'; -COMMENT ON COLUMN "Decks"."state" IS '0=ACTIVE, 1=SOFT_DELETE'; -COMMENT ON COLUMN "Chats"."type" IS 'direct, group, game'; -COMMENT ON COLUMN "Chats"."state" IS '0=ACTIVE, 1=ARCHIVE, 2=SOFT_DELETE'; -COMMENT ON COLUMN "Contacts"."type" IS '0=BUG, 1=PROBLEM, 2=QUESTION, 3=SALES, 4=OTHER'; -COMMENT ON COLUMN "Contacts"."state" IS '0=ACTIVE, 1=RESOLVED, 2=SOFT_DELETE'; -COMMENT ON COLUMN "Games"."state" IS '0=WAITING, 1=ACTIVE, 2=FINISHED, 3=CANCELLED'; -COMMENT ON COLUMN "Games"."logintype" IS '0=PUBLIC, 1=PRIVATE, 2=ORGANIZATION'; - --- Grant permissions for application user --- Note: Replace 'serpentrace_app' with your actual application database user --- GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO serpentrace_app; --- GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO serpentrace_app; --- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO serpentrace_app; \ No newline at end of file +-- This script was generated by the ERD tool in pgAdmin 4. +-- Please log an issue at https://github.com/pgadmin-org/pgadmin4/issues/new/choose if you find any bugs, including reproduction steps. +BEGIN; + +-- =================================================================== +-- STEP 1: Enable Required Extensions +-- =================================================================== +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +-- =================================================================== +-- STEP 2: Create Tables +-- =================================================================== + +CREATE TABLE IF NOT EXISTS public."ChatArchives" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + "chatId" uuid NOT NULL, + "archivedMessages" json NOT NULL, + "archivedAt" timestamp without time zone NOT NULL, + "createDate" timestamp without time zone NOT NULL DEFAULT now(), + "chatType" character varying(50) COLLATE pg_catalog."default" NOT NULL, + "chatName" character varying(255) COLLATE pg_catalog."default", + "gameId" uuid, + participants uuid[] NOT NULL, + CONSTRAINT "PK_fe62979fc2061d7afe278d3f14e" PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS public."Chats" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + type character varying(50) COLLATE pg_catalog."default" NOT NULL DEFAULT 'direct'::character varying, + name character varying(255) COLLATE pg_catalog."default", + "gameId" uuid, + "createdBy" uuid, + users uuid[] NOT NULL, + messages json NOT NULL DEFAULT '[]'::json, + "lastActivity" timestamp without time zone, + "createDate" timestamp without time zone NOT NULL DEFAULT now(), + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + state integer NOT NULL DEFAULT 0, + "archiveDate" timestamp without time zone, + CONSTRAINT "PK_64c36c2b8d86a0d5de4cf64de8d" PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS public."Contacts" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + name character varying(255) COLLATE pg_catalog."default" NOT NULL, + email character varying(255) COLLATE pg_catalog."default" NOT NULL, + userid uuid, + type integer NOT NULL, + txt text COLLATE pg_catalog."default" NOT NULL, + state integer NOT NULL DEFAULT 0, + "createDate" timestamp without time zone NOT NULL DEFAULT now(), + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + "adminResponse" text COLLATE pg_catalog."default", + "responseDate" timestamp without time zone, + "respondedBy" uuid, + CONSTRAINT "PK_68782cec65c8eef577c62958273" PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS public."Decks" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + name character varying(255) COLLATE pg_catalog."default" NOT NULL, + type integer NOT NULL, + user_id uuid NOT NULL, + creation_date timestamp without time zone NOT NULL DEFAULT now(), + cards json NOT NULL, + played_number integer NOT NULL DEFAULT 0, + ctype integer NOT NULL DEFAULT 0, + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + state integer NOT NULL DEFAULT 0, + organization_id uuid, + CONSTRAINT "PK_001f26cb3ec39c1f25269943473" PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS public."Games" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + gamecode character varying(10) COLLATE pg_catalog."default" NOT NULL, + maxplayers integer NOT NULL, + logintype integer NOT NULL DEFAULT 0, + boardsize integer NOT NULL DEFAULT 50, + "createdBy" uuid NOT NULL, + organizationid uuid, + decks jsonb NOT NULL DEFAULT '[]'::jsonb, + playerids uuid[] NOT NULL DEFAULT '{}'::uuid[], + "winnerId" uuid, + state integer NOT NULL DEFAULT 0, + "createDate" timestamp without time zone NOT NULL DEFAULT now(), + start_date timestamp without time zone, + "finishDate" timestamp without time zone, + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + "organizationId" uuid, + CONSTRAINT "PK_1950492f583d31609c5e9fbbe12" PRIMARY KEY (id), + CONSTRAINT "UQ_9d52c646079cbe6f242a85c5c41" UNIQUE (gamecode) +); + +CREATE TABLE IF NOT EXISTS public."Organizations" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + name character varying(255) COLLATE pg_catalog."default" NOT NULL, + contactfname character varying(100) COLLATE pg_catalog."default" NOT NULL, + contactlname character varying(100) COLLATE pg_catalog."default" NOT NULL, + contactphone character varying(20) COLLATE pg_catalog."default" NOT NULL, + contactemail character varying(255) COLLATE pg_catalog."default" NOT NULL, + state integer NOT NULL DEFAULT 0, + regdate timestamp without time zone NOT NULL DEFAULT now(), + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + url character varying(500) COLLATE pg_catalog."default", + userinorg integer NOT NULL DEFAULT 0, + "maxOrganizationalDecks" integer, + CONSTRAINT "PK_e0690a31419f6666194423526f2" PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS public."Users" +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + orgid uuid, + username character varying(100) COLLATE pg_catalog."default" NOT NULL, + password character varying(255) COLLATE pg_catalog."default" NOT NULL, + email character varying(255) COLLATE pg_catalog."default" NOT NULL, + fname character varying(100) COLLATE pg_catalog."default" NOT NULL, + lname character varying(100) COLLATE pg_catalog."default" NOT NULL, + token character varying(255) COLLATE pg_catalog."default", + "TokenExpires" timestamp without time zone, + phone character varying(20) COLLATE pg_catalog."default", + state integer NOT NULL DEFAULT 0, + regdate timestamp without time zone NOT NULL DEFAULT now(), + "updateDate" timestamp without time zone NOT NULL DEFAULT now(), + "Orglogindate" timestamp without time zone, + CONSTRAINT "PK_16d4f7d636df336db11d87413e3" PRIMARY KEY (id), + CONSTRAINT "UQ_3c3ab3f49a87e6ddb607f3c4945" UNIQUE (email), + CONSTRAINT "UQ_ffc81a3b97dcbf8e320d5106c0d" UNIQUE (username) +); + +CREATE TABLE IF NOT EXISTS public.migrations +( + id serial NOT NULL, + "timestamp" bigint NOT NULL, + name character varying COLLATE pg_catalog."default" NOT NULL, + CONSTRAINT "PK_8c82d7f526340ab734260ea46be" PRIMARY KEY (id) +); + +ALTER TABLE IF EXISTS public."Decks" + ADD CONSTRAINT "FK_06ee28f90d68543a03b14aebe13" FOREIGN KEY (organization_id) + REFERENCES public."Organizations" (id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; + + +ALTER TABLE IF EXISTS public."Decks" + ADD CONSTRAINT "FK_a39059433e29882e1309d3a5e70" FOREIGN KEY (user_id) + REFERENCES public."Users" (id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; + + +ALTER TABLE IF EXISTS public."Games" + ADD CONSTRAINT "FK_330362bff8b25bb573f31fb4023" FOREIGN KEY ("winnerId") + REFERENCES public."Users" (id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; + + +ALTER TABLE IF EXISTS public."Games" + ADD CONSTRAINT "FK_e3c4e8898fa026a5551aefc4f62" FOREIGN KEY ("organizationId") + REFERENCES public."Organizations" (id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; + + +ALTER TABLE IF EXISTS public."Games" + ADD CONSTRAINT "FK_f32db60863a8a393b30aa222cd5" FOREIGN KEY ("createdBy") + REFERENCES public."Users" (id) MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; + +END; \ No newline at end of file