Skip to content
Merged
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ next-env.d.ts
# testing
/test-results
/app/test
/app/og-generator
/api-index

# Agents
Expand All @@ -59,3 +58,9 @@ skills-lock.json
studio_audit_report.md
server_audit_report.md
github_issues_to_create.md
portfolio_subdomains_plan.md
portfolio_static_rendering.md
portfolio_nextjs_architecture.md
portfolio_nextjs_static_production.md
portfolio_production_comparison.md
portfolio_system_specification.md
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "apps/portfolio/template-library"]
path = apps/portfolio/template-library
url = https://github.com/VeriWorkly/portfolio-templates.git
branch = main
17 changes: 17 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,20 @@ The Geist font family is used throughout for its modern, clean appearance.
- **Max-Width**: `1280px` (`max-w-7xl`)
- **Horizontal Padding**: `px-4` (Mobile), `px-6` (Tablet), `px-8` (Desktop)
- **Vertical Spacing**: `space-y-16` to `space-y-24` between sections.

## Portfolio Studio

The portfolio product is a system-managed app surface. It extends the platform
system without introducing a separate brand.

- **Marketing pages**: asymmetric editorial product tour with a structured
template gallery.
- **App pages**: workbench layout with grouped editing cards, contextual help,
publish readiness, and a persistent private preview.
- **Public templates**: may use distinct local palettes and typography to give
portfolio owners a real creative choice. Template palettes must be declared as
named CSS tokens in each template stylesheet.
- **Motion**: CSS-first reveal, hover lift, and state transitions. Spatial motion
collapses under `prefers-reduced-motion`.
- **Editor stance**: section-aware inputs, plain-language guidance, compatible
snapshot parsing, visible focus, and no destructive action without a label.
2 changes: 1 addition & 1 deletion apps/blog-platform/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@veriworkly/blog-platform",
"version": "3.10.2",
"version": "3.11.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
2 changes: 1 addition & 1 deletion apps/docs-platform/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@veriworkly/docs-platform",
"version": "3.10.2",
"version": "3.11.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
46 changes: 37 additions & 9 deletions apps/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

NODE_ENV=development
PORT=8080
TRUST_PROXY=true
TRUST_PROXY=1

# Max in-memory entries (leave empty for default)
MAX_MEMORY_ENTRIES=
Expand Down Expand Up @@ -71,8 +71,8 @@ AUTH_BASE_URL=http://localhost:8080
# Session TTL (30 days)
AUTH_SESSION_TTL_SECONDS=2592000

# Reset TTL on activity (true | false)
AUTH_SESSION_RESET_TTL_ON_USE=true
# Reset TTL on activity (seconds)
AUTH_SESSION_RESET_TTL_ON_USE=86400

# Enable session caching
AUTH_SESSION_CACHE_ENABLED=true
Expand Down Expand Up @@ -141,15 +141,43 @@ GITHUB_SYNC_TIMEZONE=
# Internal API protection key
INTERNAL_SYNC_API_KEY=

# =========================================================
# 🌐 Portfolio Subdomain Builder
# =========================================================
PORTFOLIO_URL=http://localhost:3004
PORTFOLIO_REVALIDATE_SECRET=dev-revalidate-secret

# =========================================================
# Portfolio Pro Billing (Dodo Payments)
# =========================================================

PORTFOLIO_GRACE_DAYS=7
DODO_PAYMENTS_API_KEY=
DODO_PAYMENTS_WEBHOOK_SECRET=
DODO_PAYMENTS_ENVIRONMENT=test_mode
DODO_PAYMENTS_MONTHLY_PRODUCT_ID=
DODO_PAYMENTS_ANNUAL_PRODUCT_ID=
DODO_PAYMENTS_CHECKOUT_RETURN_URL=http://portfolio.localhost:3004/billing?checkout=complete
DODO_PAYMENTS_CHECKOUT_CANCEL_URL=http://portfolio.localhost:3004/billing?checkout=cancelled
DODO_PAYMENTS_PORTAL_RETURN_URL=http://portfolio.localhost:3004/billing

# =========================================================
# Portfolio Media (Cloudflare R2)
# =========================================================

R2_ENDPOINT=
R2_BUCKET=
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_PUBLIC_BASE_URL=

# =========================================================
# 🚪 API Key Configuration
# =========================================================

hashSecret= "dev-api-key-secret"
authCacheTtlSeconds= 300
lastUsedTouchIntervalSeconds= 300
defaultRateLimit: 20
defaultScopes: user:read
defaultKeyLifetimeDays: 365
API_KEY_HASH_SECRET=dev-api-key-secret
API_KEY_AUTH_CACHE_TTL_SECONDS=300
API_KEY_LAST_USED_TOUCH_INTERVAL_SECONDS=300
API_KEY_DEFAULT_RATE_LIMIT=20
API_KEY_DEFAULT_SCOPES=user:read
API_KEY_DEFAULT_LIFETIME_DAYS=365
33 changes: 16 additions & 17 deletions apps/server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,37 @@ WORKDIR /app
ENV NODE_ENV=production

COPY package*.json ./
COPY prisma ./prisma
COPY apps/server/package.json ./apps/server/package.json

# 1. Install all dependencies
RUN npm ci --include=dev --legacy-peer-deps
# Build with repository root as context:
# docker build -f apps/server/Dockerfile .
RUN npm ci --workspace=@veriworkly/server --include=dev --legacy-peer-deps

COPY tsconfig.json ./
COPY src ./src
COPY apps/server/prisma ./apps/server/prisma
COPY apps/server/tsconfig.json ./apps/server/tsconfig.json
COPY apps/server/src ./apps/server/src

# 2. Generate Prisma, Build, and Fix Extensions
RUN npx prisma generate \
&& npm run build \
&& npx resolve-tspaths \
RUN npm run db:generate --workspace=@veriworkly/server \
&& npm run build --workspace=@veriworkly/server \
&& npm prune --omit=dev --legacy-peer-deps

FROM node:${NODE_VERSION}-alpine AS runner
WORKDIR /app
WORKDIR /app/apps/server

ENV NODE_ENV=production
ENV PORT=8080

# 3. UPDATED FIX: Install OpenSSL 1.1 from the v3.16 repository
RUN apk add --no-cache openssl

# Security: Run as non-root user
RUN addgroup -S app && adduser -S app -G app

COPY --from=build /app/package*.json ./
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/prisma ./prisma
COPY --from=build /app/package*.json /app/
COPY --from=build /app/node_modules /app/node_modules
COPY --from=build /app/apps/server/package.json ./package.json
COPY --from=build /app/apps/server/dist ./dist
COPY --from=build /app/apps/server/prisma ./prisma

USER app
EXPOSE 8080

CMD ["node", "dist/index.js"]
CMD ["node", "dist/index.js"]
34 changes: 17 additions & 17 deletions apps/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@veriworkly/server",
"version": "3.10.2",
"version": "3.11.0",
"description": "VeriWorkly Resume Backend API",
"main": "dist/index.js",
"type": "module",
Expand All @@ -18,44 +18,44 @@
"db:push": "prisma db push",
"db:migrate": "prisma migrate dev",
"db:studio": "prisma studio",
"db:generate": "prisma generate",
"sync:github": "tsx src/jobs/runGithubSyncOnce.ts",
"test": "vitest run",
"test:watch": "vitest --watch"
},
"dependencies": {
"@better-auth/prisma-adapter": "^1.6.11",
"@opentelemetry/api": "^1.9.1",
"@aws-sdk/client-s3": "^3.1057.0",
"@aws-sdk/s3-request-presigner": "^3.1057.0",
"@better-auth/prisma-adapter": "^1.6.12",
"@prisma/adapter-pg": "^7.8.0",
"@prisma/client": "^7.8.0",
"@prisma/config": "^7.8.0",
"better-auth": "^1.6.11",
"better-auth": "^1.6.12",
"cors": "^2.8.6",
"dodopayments": "^2.32.1",
"dotenv": "^17.4.2",
"express": "^4.19.2",
"express-rate-limit": "^8.4.1",
"helmet": "^7.1.0",
"ioredis": "^5.10.1",
"express": "^4.22.2",
"helmet": "^7.2.0",
"node-cron": "^4.2.1",
"nodemailer": "^8.0.6",
"pg": "^8.20.0",
"rate-limit-redis": "^4.3.1",
"nodemailer": "^8.0.10",
"pg": "^8.21.0",
"redis": "^5.12.1",
"uuid": "^14.0.0",
"vitest": "^4.1.5",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^4.17.21",
"@types/node": "^20.19.39",
"@types/express": "^4.17.25",
"@types/node": "^20.19.41",
"@types/nodemailer": "^7.0.11",
"@types/pg": "^8.20.0",
"eslint": "^9",
"prettier": "^3.8.3",
"prisma": "^7.8.0",
"resolve-tspaths": "^0.8.23",
"tsc-alias": "^1.8.16",
"tsx": "^4.21.0",
"typescript": "^5.3.3"
"tsc-alias": "^1.8.17",
"tsx": "^4.22.3",
"typescript": "^5.9.3",
"vitest": "^4.1.7"
}
}
Loading
Loading