Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions frontend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.git
**/.git

node_modules
**/node_modules

.next
**/.next

dist
**/dist

coverage
**/coverage

*.log
**/*.log

.DS_Store
**/.DS_Store
8 changes: 8 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ RUN if [ "$name" = "desktop" ]; then \
cp -r ./desktop/prisma/region/migrations desktop/.next/standalone/desktop/prisma/region/migrations; \
fi
RUN if [ "$name" = "devbox" ]; then \
if [ -d "./providers/devbox/prisma/cockroach/migrations" ]; then \
mkdir -p ./providers/devbox/.next/standalone/providers/devbox/prisma/cockroach && \
cp -r ./providers/devbox/prisma/cockroach/migrations ./providers/devbox/.next/standalone/providers/devbox/prisma/cockroach/; \
fi; \
if [ -d "./providers/devbox/prisma/postgresql/migrations" ]; then \
mkdir -p ./providers/devbox/.next/standalone/providers/devbox/prisma/postgresql && \
cp -r ./providers/devbox/prisma/postgresql/migrations ./providers/devbox/.next/standalone/providers/devbox/prisma/postgresql/; \
fi; \
if [ -d "./providers/devbox/prisma/migrations" ]; then \
mkdir -p ./providers/devbox/.next/standalone/providers/devbox/prisma && \
cp -r ./providers/devbox/prisma/migrations ./providers/devbox/.next/standalone/providers/devbox/prisma/; \
Expand Down
3 changes: 3 additions & 0 deletions frontend/providers/devbox/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ ACCOUNT_URL=
# in dev: postgresql://username:password@127.0.0.1:26257/devboxdb?connection_limit=50&pool_timeout=20
# in prod: postgresql://username:password@cockroachdb-global.cockroach-operator-system:26257/devboxdb?connection_limit=50&pool_timeout=20
DATABASE_URL=
# database provider for prisma runtime/migration routing
# values: cockroachdb (default) | postgresql
DATABASE_PROVIDER="cockroachdb"
# url for template retag
# in dev: http://127.0.0.1:8092
# in prod: http://devbox-service.devbox-system.svc.cluster.local:8092
Expand Down
4 changes: 4 additions & 0 deletions frontend/providers/devbox/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ COPY --from=builder /app/package.json ./package.json
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Next standalone includes prisma schemas/clients but not migrations.
# Keep both providers' migrations for initContainer migrate deploy.
COPY --from=builder --chown=nextjs:nodejs /app/prisma/cockroach/migrations ./providers/devbox/prisma/cockroach/migrations
COPY --from=builder --chown=nextjs:nodejs /app/prisma/postgresql/migrations ./providers/devbox/prisma/postgresql/migrations

USER nextjs

Expand Down
33 changes: 23 additions & 10 deletions frontend/providers/devbox/deploy/manifests/deploy.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,34 @@ spec:
env:
- name: DATABASE_URL
value: {{ .databaseUrl }} # -nsealos cm desktop-frontend-config ->database->global + devbox
- name: DATABASE_PROVIDER
value: "{{ default "cockroachdb" .databaseProvider }}"
command:
- sh
- -c
args:
- |-
cd /app/providers/devbox
MIGRATION="20260125094114_add_template_repository_kind"
HAS_MIGRATION=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM _prisma_migrations WHERE migration_name='${MIGRATION}' AND rolled_back_at IS NULL LIMIT 1;")
if [ "$HAS_MIGRATION" = "1" ]; then
prisma migrate deploy
exit 0
DB_PROVIDER="${DATABASE_PROVIDER:-cockroachdb}"
SCHEMA_PATH="./prisma/cockroach/schema.prisma"
if [ "$DB_PROVIDER" = "postgresql" ] || [ "$DB_PROVIDER" = "postgres" ] || [ "$DB_PROVIDER" = "pg" ]; then
SCHEMA_PATH="./prisma/postgresql/schema.prisma"
HAS_UUID_FN=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_proc WHERE proname='gen_random_uuid' LIMIT 1;")
if [ "$HAS_UUID_FN" != "1" ]; then
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c 'CREATE OR REPLACE FUNCTION public.gen_random_uuid() RETURNS uuid LANGUAGE SQL VOLATILE AS $func$ SELECT md5(random()::text || clock_timestamp()::text || txid_current()::text)::uuid; $func$;'
fi
MIGRATION="20260125094114_add_template_repository_kind"
HAS_MIGRATION=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM _prisma_migrations WHERE migration_name='${MIGRATION}' AND rolled_back_at IS NULL LIMIT 1;")
if [ "$HAS_MIGRATION" = "1" ]; then
prisma migrate deploy --schema "$SCHEMA_PATH"
exit 0
fi
HAS_ENUM=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_enum e JOIN pg_type t ON t.oid = e.enumtypid WHERE t.typname IN ('TemplateRepositoryKind','template_repository_kind') AND e.enumlabel = 'SERVICE' LIMIT 1;")
if [ "$HAS_ENUM" = "1" ]; then
prisma migrate resolve --schema "$SCHEMA_PATH" --applied "$MIGRATION"
fi
fi
HAS_ENUM=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_enum e JOIN pg_type t ON t.oid = e.enumtypid WHERE t.typname IN ('TemplateRepositoryKind','template_repository_kind') AND e.enumlabel = 'SERVICE' LIMIT 1;")
if [ "$HAS_ENUM" = "1" ]; then
prisma migrate resolve --applied "$MIGRATION"
fi
prisma migrate deploy
prisma migrate deploy --schema "$SCHEMA_PATH"
containers:
- name: devbox-frontend
env:
Expand Down Expand Up @@ -103,6 +114,8 @@ spec:
value: {{ .regionUid }} # -nsealos cm desktop-frontend-config ->regionUid
- name: DATABASE_URL
value: {{ .databaseUrl }} # -nsealos cm desktop-frontend-config ->database->global + devbox
- name: DATABASE_PROVIDER
value: "{{ default "cockroachdb" .databaseProvider }}"
- name: ENABLE_IMPORT_FEATURE
value: 'false'
- name: ENABLE_WEBIDE_FEATURE
Expand Down
5 changes: 4 additions & 1 deletion frontend/providers/devbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"ts-lint": "tsc --noEmit",
"link-sdk": "rm -rf node_modules/sealos-desktop-sdk && yalc link sealos-desktop-sdk",
"unlink-sdk": "yalc remove --all && pnpm install sealos-desktop-sdk",
"gen-client": "prisma generate --schema ./prisma/schema.prisma",
"gen-client": "prisma generate --schema ./prisma/cockroach/schema.prisma && prisma generate --schema ./prisma/postgresql/schema.prisma",
"migrate:deploy:cockroach": "prisma migrate deploy --schema ./prisma/cockroach/schema.prisma",
"migrate:deploy:postgresql": "prisma migrate deploy --schema ./prisma/postgresql/schema.prisma",
"migrate:resolve:postgresql": "prisma migrate resolve --schema ./prisma/postgresql/schema.prisma",
"postinstall": "pnpm gen-client",
"ui": "pnpm dlx shadcn@latest add"
},
Expand Down
20 changes: 20 additions & 0 deletions frontend/providers/devbox/prisma/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Prisma Layout (No Default Entry)

To avoid accidental misuse, this repo intentionally does **not** keep:

- `prisma/schema.prisma`
- `prisma/migrations/*`

Always use an explicit schema:

- CockroachDB
- schema: `prisma/cockroach/schema.prisma`
- deploy: `pnpm migrate:deploy:cockroach`
- PostgreSQL
- schema: `prisma/postgresql/schema.prisma`
- deploy: `pnpm migrate:deploy:postgresql`

Runtime client routing is controlled by `DATABASE_PROVIDER`:

- `cockroachdb` (default)
- `postgresql`
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
generator globalClient {
provider = "prisma-client-js"
output = "./generated/client"
output = "../generated/client"
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
-- CreateEnum
CREATE TYPE "TemplateRepositoryKind" AS ENUM ('FRAMEWORK', 'OS', 'LANGUAGE', 'CUSTOM');

-- Ensure gen_random_uuid() exists on PostgreSQL variants (e.g. KingbaseES)
CREATE OR REPLACE FUNCTION public.gen_random_uuid()
RETURNS uuid
LANGUAGE SQL
VOLATILE
AS $func$
SELECT md5(random()::text || clock_timestamp()::text || txid_current()::text)::uuid;
$func$;

-- CreateTable
CREATE TABLE "User" (
"uid" UUID NOT NULL DEFAULT gen_random_uuid(),
"regionUid" TEXT NOT NULL,
"namespaceId" TEXT NOT NULL,
"deletedAt" TIMESTAMPTZ(3),
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"isDeleted" BOOL DEFAULT false,

CONSTRAINT "User_pkey" PRIMARY KEY ("uid")
);

-- CreateTable
CREATE TABLE "Organization" (
"uid" UUID NOT NULL DEFAULT gen_random_uuid(),
"id" TEXT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"deletedAt" TIMESTAMPTZ(3),
"isDeleted" BOOL DEFAULT false,
"name" TEXT NOT NULL,

CONSTRAINT "Organization_pkey" PRIMARY KEY ("uid")
);

-- CreateTable
CREATE TABLE "UserOrganization" (
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"userUid" UUID NOT NULL,
"organizationUid" UUID NOT NULL,

CONSTRAINT "UserOrganization_pkey" PRIMARY KEY ("organizationUid","userUid")
);

-- CreateTable
CREATE TABLE "TemplateRepository" (
"uid" UUID NOT NULL DEFAULT gen_random_uuid(),
"deletedAt" TIMESTAMPTZ(3),
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"kind" "TemplateRepositoryKind" NOT NULL,
"organizationUid" TEXT NOT NULL,
"isPublic" BOOL NOT NULL DEFAULT false,
"iconId" TEXT,
"isDeleted" BOOL DEFAULT false,

CONSTRAINT "TemplateRepository_pkey" PRIMARY KEY ("uid")
);

-- CreateTable
CREATE TABLE "Template" (
"uid" UUID NOT NULL DEFAULT gen_random_uuid(),
"name" TEXT NOT NULL,
"templateRepositoryUid" TEXT NOT NULL,
"devboxReleaseImage" TEXT,
"image" TEXT NOT NULL,
"config" TEXT NOT NULL,
"deletedAt" TIMESTAMPTZ(3),
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"parentUid" UUID,
"isDeleted" BOOL DEFAULT false,

CONSTRAINT "Template_pkey" PRIMARY KEY ("uid")
);

-- CreateTable
CREATE TABLE "Tag" (
"uid" UUID NOT NULL DEFAULT gen_random_uuid(),
"name" TEXT NOT NULL,
"zhName" TEXT,
"enName" TEXT,

CONSTRAINT "Tag_pkey" PRIMARY KEY ("uid")
);

-- CreateTable
CREATE TABLE "TemplateRepositoryTag" (
"templateRepositoryUid" UUID NOT NULL,
"tagUid" UUID NOT NULL,

CONSTRAINT "TemplateRepositoryTag_pkey" PRIMARY KEY ("templateRepositoryUid","tagUid")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_isDeleted_regionUid_namespaceId_key" ON "User"("isDeleted", "regionUid", "namespaceId");

-- CreateIndex
CREATE UNIQUE INDEX "Organization_id_key" ON "Organization"("id");

-- CreateIndex
CREATE INDEX "UserOrganization_userUid_idx" ON "UserOrganization"("userUid");

-- CreateIndex
CREATE INDEX "UserOrganization_createdAt_idx" ON "UserOrganization"("createdAt");

-- CreateIndex
CREATE INDEX "TemplateRepository_isDeleted_isPublic_idx" ON "TemplateRepository"("isDeleted", "isPublic");

-- CreateIndex
CREATE UNIQUE INDEX "TemplateRepository_isDeleted_name_key" ON "TemplateRepository"("isDeleted", "name");

-- CreateIndex
CREATE UNIQUE INDEX "Template_isDeleted_templateRepositoryUid_name_key" ON "Template"("isDeleted", "templateRepositoryUid", "name");

-- CreateIndex
CREATE INDEX "TemplateRepositoryTag_tagUid_idx" ON "TemplateRepositoryTag"("tagUid");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "TagType" AS ENUM ('PROGRAMMING_LANGUAGE', 'USE_CASE', 'OFFICIAL_CONTENT');

-- AlterTable
ALTER TABLE "Tag" ADD COLUMN "type" "TagType" NOT NULL DEFAULT 'OFFICIAL_CONTENT';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- upgrade region
-- DropIndex
DROP INDEX "TemplateRepository_isDeleted_name_key";

-- add regionUid column
ALTER TABLE "TemplateRepository"
ADD COLUMN "regionUid" TEXT NOT NULL default '00000000-0000-0000-0000-000000000000';
ALTER TABLE "TemplateRepository"
ALTER COLUMN "regionUid" DROP DEFAULT;

-- CreateIndex
CREATE INDEX "TemplateRepository_isDeleted_createdAt_idx" ON "TemplateRepository" ("isDeleted", "createdAt");

-- CreateIndex
CREATE UNIQUE INDEX "TemplateRepository_isDeleted_regionUid_name_key" ON "TemplateRepository" ("isDeleted", "regionUid", "name");

-- AlterTable
ALTER TABLE public."TemplateRepository" alter column "organizationUid" type uuid using "organizationUid"::uuid;
-- AlterTable
DROP INDEX "Template_isDeleted_templateRepositoryUid_name_key";
ALTER TABLE "Template" ALTER COLUMN "templateRepositoryUid" type uuid using "templateRepositoryUid"::uuid;
CREATE UNIQUE INDEX "Template_isDeleted_templateRepositoryUid_name_key" ON "Template" ("isDeleted", "templateRepositoryUid", "name");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Add usage count field to TemplateRepository
ALTER TABLE "TemplateRepository" ADD COLUMN "usageCount" INT4 NOT NULL DEFAULT 0;

-- Create index on usageCount for better query performance
CREATE INDEX "TemplateRepository_isDeleted_usageCount_idx" ON "TemplateRepository"("isDeleted", "usageCount");
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "TemplateRepositoryKind" ADD VALUE 'SERVICE';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
Loading
Loading