AR Try-On — Internal Code Documentation
This document is intended for developers maintaining or extending the WEARFITS Node.js server. It covers system architecture, role-based access control, core processing flows, data and storage layers, ML models, environment configuration, deployment, and versioning.
1. System Architecture
WEARFITS uses a modular architecture where the core Express server handles routing and asset management, while specialized workers orchestrated via a custom queue system handle heavy computation (3D fitting, photogrammetry, baking).
graph TD
subgraph Client
SDK[JS SDK / Try-on Viewer]
DASH[Dashboard UI]
end
subgraph Server ["Node.js / Express"]
RT[Router / Controllers]
MC[Modules Controller / Queue]
SRV["src/ Service Layer"]
PR[Prisma ORM]
end
subgraph Workers [Child Processes]
WC[Converter Worker]
WP[Photogrammetry Worker]
WB[Bake / Blender Worker]
end
subgraph Data
GCS[Google Cloud Storage]
PG[(PostgreSQL)]
JSON[Local JSON Database]
end
SDK <--> RT
DASH <--> RT
RT --> SRV
SRV --> MC
MC <--> WC & WP & WB
SRV <--> PR <--> PG
SRV <--> JSON
SRV <--> GCS
A secondary view showing the full request path including external dependencies:
graph TD
A[External Clients / Browser SDK] -->|HTTPS / WSS| B[Express Server]
B --> C[Router / Controllers]
C --> D["Service Layer / src"]
D --> E[Prisma ORM]
D --> F[Google Cloud Storage]
D --> G[Local JSON DB / FS]
E --> H[(PostgreSQL)]
D --> I["External APIs: BoldMetrics, OpenAI"]
B <--> J[Socket.io]
Key Components
| Component | File | Responsibility |
|---|---|---|
| Entry point | server.js |
Initializes Express, middleware (express-minify, compression), HTTP/HTTPS, Socket.io, and routes |
| Global config | src/globals.js |
All directory paths, environment variables, bucket names, application constants, and proxy-based persistent config |
| Core utilities | src/myUtils.js |
Bundle creation, script minification, thread execution, try-on version saving, addMesh() (triggers Slack notification on new model upload) |
| Threaded I/O | src/myUtilsThreaded.js |
Promise-based file and cloud storage abstraction; switches between local FS and GCS via CLOUD_MODE |
| Worker control | src/modules_controller.js |
Queue management and child-process lifecycle for converter, photogrammetry, and bake workers |
| WebSocket | src/socketio.js |
Real-time progress events to clients |
| NextAuth bridge | src/nextAuthSession.js |
Maps NextAuth session tokens to legacy user roles |
| Notifications | src/notifications.js |
Non-blocking Slack webhook calls (new model uploads, etc.) |
2. User Roles & Permissions
The application uses a numeric permission-level system combined with specific role flags stored on the user object.
| Level | Name | Key Property | Capabilities |
|---|---|---|---|
| 1 | User | Authenticated | Upload models; view personal objects |
| 1.5 | Low Admin | lowAdmin: true |
Read-only access to global objects and status metrics |
| 2 | Garment Admin | garmentAdmin: true |
Manage the photogrammetry queue (/queue_control) |
| 3 | Full Admin | admin: true |
Complete access to /admin, /database-viewer, and global configurations |
Authentication Providers
- Legacy — User data stored in
var/database/users.json. Passwords hashed with bcrypt. - NextAuth — Integrated with
dash.wearfits.com. Users are resolved by email and mapped to legacy role flags viasrc/nextAuthSession.js. - API Keys — Server-to-server authentication for integrators. Keys are validated against records in Prisma/PostgreSQL (
ApiKeymodel).
Always verify permissions in route handlers before processing requests. Use the proxy pattern available in
globals.persistentfor all database interactions.
3. Core Logic Flows
3.1 Autofit & Upload Process
Triggered when a GLB file is uploaded via POST /tryon/api/upload_shoe:
Client uploads GLB
└─► addModelFromGLBFile() — saves file + textures to var/objects/
└─► mc.queue.add('autofit') — pushes task to tryon queue
└─► tryon worker — Python/Blender scripts compute template foot alignment
└─► on_autofit_finished()
├─► updates object properties in objects.json
└─► triggers 'bake' task if required
addModelFromGLBFilepersists the uploaded GLB and extracts textures.- An
autofittask is pushed to thetryonqueue managed bymodules_controller. - The tryon worker (spawned child process running Python/Blender) computes foot alignment against the template.
on_autofit_finishedwrites updated object properties back toobjects.jsonand schedules abakepass when necessary.src/notifications.jsfires a non-blocking Slack webhook alert for new models (re-uploads are silently ignored).
3.2 Photogrammetry Task Flow
Triggered when a client uploads a ZIP archive of photos to POST /photogrammetry/upload:
Client uploads ZIP archive
└─► Task record written to var/database/tasks.json
└─► modules_controller picks up task
└─► photogrammetry worker (child process)
├─► emits Socket.io events: 'preprocessing' → 'building' → 'postprocessing'
└─► on success: 3D model moved to var/objects/
- The ZIP is validated and extracted by
src/photogrammetry_utils.js(JPEG, PNG, and HEIC images only). - A task record is persisted to
var/database/tasks.json. modules_controllerassigns the task to a photogrammetry worker.- The worker emits granular progress events over Socket.io:
preprocessing,building,postprocessing. - On success the resulting 3D model is moved to
var/objects/and the task status is updated.
4. Database & Storage
4.1 Prisma (PostgreSQL)
Used primarily for modern authentication and API key management.
| Model | Purpose |
|---|---|
User |
Authenticated dashboard user |
Account |
OAuth provider account link |
Session |
Active NextAuth session |
ApiKey |
Server-to-server integration credentials |
- Schema:
prisma/schema.prisma - Client generation:
npx prisma generate(runs automatically onnpm install) - Schema sync:
npx prisma db push - GUI browser:
npx prisma studio - Production secret:
NEXTAUTH_DATABASE_URLstored in Google Cloud Secret Manager; the App Engine service account (wearfits-dev@appspot.gserviceaccount.com) requires the Secret Manager Secret Accessor role.
4.2 Legacy JSON Database
Core business data stored as JSON files in var/database/, loaded at startup and cached in globals.
| File | Global Cache | Contents |
|---|---|---|
objects.json |
globals.cachedObjectProperties |
All 3D model metadata |
users.json |
— | Legacy user accounts and role flags |
config.json |
globals.persistent |
App configuration, tryon version info |
tokens.json |
— | Authentication tokens |
tasks.json |
— | Photogrammetry task queue |
4.3 Hybrid Storage via myUtilsThreaded.js
The storage abstraction layer provides a uniform API regardless of storage mode:
globals.CLOUD_MODE = true → operations target Google Cloud Storage
globals.CLOUD_MODE = false → operations target local filesystem (var/)
init_storage() in myUtilsThreaded.js validates bucket existence at startup. If the main bucket is unreachable the system automatically falls back to local mode. Cloud operations are throttled to max_cloud_request_count = 200 to avoid rate limiting on batch operations.
router/assets.js issues res.redirect() to cloud URLs when CLOUD_MODE is enabled, meaning assets are served directly from GCS rather than proxied through the Node.js process.
4.4 GCS Bucket Structure
| Global Variable | Purpose |
|---|---|
CLOUD_MAIN_BUCKET_NAME |
General asset storage (default) |
CLOUD_SECURE_BUCKET_NAME |
Sensitive files |
CLOUD_FR_BUCKET_NAME |
Fitting room assets |
CLOUD_LABELER_BUCKET_NAME |
Image labeling data |
CLOUD_PHOTOGRAMMETRY_BUCKET_NAME |
Photogrammetry processing files |
CLOUD_MEASUREMENTS_BUCKET_NAME |
User measurement data |
4.5 Local var/ Directory Layout
The var/ directory (root defined by globals.VAR_DIR, overridable via NODEJS_VAR) is the primary runtime storage location:
var/
├── objects/ # 3D model data
├── textures/ # Processed textures
├── usdz/ # USDZ exports
├── gltf/ # GLTF exports
├── tile_materials/ # Tiled material data
├── database/ # JSON database files (config.json, users.json, tokens.json)
├── ml_models/ # Cached ML model files
├── photogrammetry/ # Photogrammetry processing outputs
├── measurements/ # User measurement data
├── labeler/ # Labeling system data
├── fr/ # Fitting room assets (cache, BVH, renderings, ZPAC)
├── tryon_versions/ # Versioned tryon app bundles (v1/, v2/, …, v{N}/)
├── tryon_bug_report/ # Try-on session bug reports
├── trash_bin/ # Soft-deleted items awaiting cleanup
├── tmp/ # General temporary files (TMP_DIR)
└── tmp_fr/ # Fitting room temporary files (TMP_FR_DIR)
5. Project Structure
WEARFITS/
├── server.js # Main entry point: Express init, middleware, routes
├── src/ # Core backend modules
│ ├── globals.js # Global config, paths, env vars, constants
│ ├── init_fs_and_logging.js # Filesystem init and log stream setup
│ ├── myUtils.js # Core utilities: bundling, logging, addMesh()
│ ├── myUtilsThreaded.js # Promise-based FS + GCS abstraction layer
│ ├── photogrammetry_utils.js # Archive extraction and image preprocessing
│ ├── socketio.js # WebSocket connection management
│ ├── child.js # Child process management
│ ├── exporters.js # 3D model file export operations
│ ├── labeler_utils.js # Labeling system utilities
│ ├── measurements_utils.js # Measurement processing utilities
│ ├── modules_controller.js # Worker module control and queue
│ ├── nextAuthSession.js # NextAuth session integration
│ ├── notifications.js # Non-blocking Slack webhook notifications
│ ├── tryon_utils.js # Try-on processing utilities
│ ├── wearfits_module_adapter.js # Module adapter layer (Blob API compatibility)
│ └── workers.js # Worker thread management
├── router/ # HTTP routes and controllers
│ ├── api.js # Main API endpoints
│ ├── assets.js # Static asset serving / cloud redirect
│ ├── fitting_room.js # Fitting room functionality
│ ├── index.js # Main pages and access log
│ ├── account.js # Authentication and account management
│ ├── tryon.js # Try-on experience routes
│ ├── photogrammetry.js # Photogrammetry upload and control routes
│ ├── labeler.js # Labeler routes
│ ├── measurements.js # Measurements routes
│ ├── integrations.js # Third-party integration routes
│ ├── server.js # Server management routes
│ └── tools.js # Utility tool routes
├── public/ # Frontend assets (client-accessible)
│ ├── js/
│ │ ├── threejs/ # Three.js libraries
│ │ ├── ml/ # ML inference scripts
│ │ ├── onnx/ # ONNX runtime files
│ │ ├── tf/ # TensorFlow.js files
│ │ ├── wearfits-core.js # Core frontend: 3D scene, camera, AR
│ │ ├── wearfits-editor.js # Garment editor interface
│ │ └── tryon_static_files.js # Static model ID → GCS URL mapping
│ ├── css/ # Stylesheets
│ └── img/ # Images and media
├── views/ # EJS templates
│ ├── blocks/ # Reusable template partials
│ ├── tryon.html # Try-on viewer entry point (GTM deferred load)
│ └── index.html # Main application entry point
├── scripts/ # External processing tools (not in request cycle)
│ ├── digitise/
│ ├── measurement/
│ ├── photogrammetry/
│ ├── reality_capture/
│ ├── usdz_converter/
│ ├── ml_train/
│ └── …
├── prisma/
│ └── schema.prisma # Prisma database schema
├── tests/
│ ├── apiTests.js # API endpoint tests
│ └── README.md
├── .github/workflows/
│ ├── test.yml # Run tests on push to master
│ └── auto-version.yml # Auto-increment build number on push
├── .githooks/
│ └── pre-push # Runs test suite before allowing push
├── app.yaml # GCP App Engine — production config
├── app_test.yaml # GCP App Engine — test environment config
└── package.json
Do not analyze files in
scripts/,var/, orviews/samples/unless directly required. These are external tools or runtime artifacts.
6. ML Models
All inference runs client-side in the browser. Models are served from cloud storage and loaded by the SDK.
6.1 Supported Inference Formats
| Format | Browser Backends | Notes |
|---|---|---|
| TensorFlow.js | WebGL, CPU, WASM | Default format; uses tf_backend option |
| ONNX | WebGL, WebNN, CPU | Enable with use_onnx=true; uses onnx_backend option |
| LiteRT (.tflite) | WebGPU, WASM | Via @litertjs/core; bundled as litert.bundle.js |
| Native | Platform-specific | High-performance path |
6.2 Pose Detection Models
| Model | Path Suffix | Size | Input | pose_quality |
Best For |
|---|---|---|---|---|---|
| Lite v2 | pose_lite_v2/ |
~5 MB | 192×192 px | 1 (default) |
Mobile, real-time |
| Full v2 | pose_full_v2/ |
~15 MB | 256×256 px | 2 |
Desktop, balanced |
| Heavy v2 | pose_heavy_v2/ |
~26 MB (7 shards) | 256×256 px | 3 |
Maximum accuracy |
Outputs: 39 keypoints + segmentation mask + 3D coordinates (Heavy v2).
// Select via URL parameter
?pose_quality=3
// Or programmatically
tryon.options.pose_mode_model_type = "heavy"; // "lite" | "full" | "heavy"
Auto Target Pin Location (added Aug 2025): Set target_pin_location=auto (or ?target_pin_location=auto) to enable automatic switching between hand targets based on proximity.
6.3 Segmentation Models
| Model | Size | Input | Notes |
|---|---|---|---|
seg_256_v1 |
~8 MB (2 shards) | 256×256 px | Initial high-res segmentation |
seg_256_v2 |
~8 MB (2 shards) | 256×256 px | Improved accuracy |
seg_256_v3 |
~8 MB (2 shards) | 256×256 px | Latest optimized version |
Models ≥256 px automatically enable full-crop mode (
auto-cropping) for optimal input framing.
6.4 Footwear Detection Models
Medium series for footwear pose detection, available in multiple resolutions:
| Resolution | Versions | ONNX Available |
|---|---|---|
| 160×160 px | v3, v4, v10 | v4 |
| 192×192 px | v4, v10 | v4 |
| 256×256 px | v3, v4, v10 | v4, v10 |
ONNX filenames: medium_160_v4.onnx, medium_192_v4.onnx, medium_256_v4.onnx, medium_256_v10.onnx.
Configure resolution with:
tryon.options.native_ml_size = 256; // 160 | 192 | 256
tryon.options.native_ml_point_set = 0; // 0 | 1 | 2
6.5 Inference Performance
| Model | Desktop (ms) | Mobile (ms) | Memory (MB) |
|---|---|---|---|
| Lite Pose | 15–25 | 40–80 | 50–100 |
| Full Pose | 25–40 | 80–150 | 100–200 |
| Heavy Pose v2 | 40–70 | 150–300 | 200–400 |
6.6 Model Loading Times (Approximate)
| Model | Size | WiFi | 3G |
|---|---|---|---|
| Lite Pose | 5 MB | 2–3 s | 8–12 s |
| Full Pose | 15 MB | 5–8 s | 20–30 s |
| Heavy Pose v2 | 26 MB | 8–12 s | 35–50 s |
| Seg 256 v3 | 8 MB | 3–5 s | 12–18 s |
6.7 Backend Configuration Reference
tryon.options = {
// Model selection
pose_mode_model_type: "full", // "lite" | "full" | "heavy"
native_ml_size: 192, // 160 | 192 | 256
// Backend
tf_backend: "webgl", // "webgl" | "cpu" | "wasm"
onnx_backend: "webgl", // "webgl" | "cpu" | "webnn"
use_onnx: false,
webnn_enabled: false, // experimental
// Quality & stability
use_additional_masking_model: false,
ignore_unstable_movements: true,
oflow_error_threshold: 10.0,
// Performance
async_mode: false,
target_pin_location: "auto",
};
7. Tech Stack
| Component | Technology |
|---|---|
| Runtime | Node.js 24.x |
| Framework | Express.js |
| Primary Database | PostgreSQL via Prisma ORM |
| Secondary Database | Local JSON files (var/database/) |
| Cloud Storage | Google Cloud Storage |
| Real-time | Socket.io v4 |
| View Engine | EJS |
| Image Processing | Sharp v0.33 |
| 3D Rendering (client) | Three.js |
| ML Inference (client) | TensorFlow.js, ONNX Runtime, LiteRT |
| Notifications | Slack Webhooks |
| External APIs | OpenAI, BoldMetrics |
8. Environment Variables
| Variable | Description | Example / Default |
|---|---|---|
PORT / NODEJS_HTTP_PORT |
Express HTTP port | 8080 |
NODEJS_HTTPS_PORT |
Express HTTPS port | 8443 |
NODEJS_VAR |
Override path for the var/ directory |
[project_root]/var |
NEXTAUTH_DATABASE_URL |
Prisma connection string (PostgreSQL) | prisma+postgres://… |
GCP_SERVICE_ACCOUNT |
JSON credentials for GCP Service Account | {…} |
CLOUD_MAIN_BUCKET_NAME |
Main GCS bucket for assets | wearfits-assets |
CLOUD_SECURE_BUCKET_NAME |
GCS bucket for sensitive files | — |
CLOUD_FR_BUCKET_NAME |
GCS bucket for fitting room assets | — |
CLOUD_LABELER_BUCKET_NAME |
GCS bucket for labeling data | — |
CLOUD_PHOTOGRAMMETRY_BUCKET_NAME |
GCS bucket for photogrammetry files | — |
CLOUD_MEASUREMENTS_BUCKET_NAME |
GCS bucket for measurement data | — |
WEARFITS_ORIGIN |
Base URL for the application | https://app.wearfits.com |
WEARFITS_CDN |
CDN URL for static assets | https://cdn.wearfits.com |
WEARFITS_PRODUCTION |
Production mode flag | 1 |
OPENAI_API_KEY |
OpenAI API key | sk-… |
BOLDMETRICS_ID / BOLDMETRICS_KEY |
BoldMetrics API credentials | — |
SLACK_WEBHOOK_URL |
Incoming webhook for Slack notifications | https://hooks.slack.com/… |
In production,
NEXTAUTH_DATABASE_URLis stored in Google Cloud Secret Manager. The App Engine service accountwearfits-dev@appspot.gserviceaccount.commust have the Secret Manager Secret Accessor role.
9. Deployment
9.1 Google Cloud Platform — App Engine (Flexible)
| Config File | Environment | Notes |
|---|---|---|
app.yaml |
Production (project: wearfits-dev) |
Use for all standard releases |
app_test.yaml |
Test | Staging/preview environment |
app_prod.yaml |
Legacy | Do not use for main production releases |
9.2 CI/CD — GitHub Actions
| Workflow | Trigger | Action |
|---|---|---|
test.yml |
Push to master |
Runs full test suite |
auto-version.yml |
Push to master |
Auto-increments build number |
9.3 Git Hooks
A pre-push hook runs the test suite before any push is allowed. Enable it with:
9.4 CLI Reference
| Command | Description |
|---|---|
npm start |
Start the application |
npm run test |
Run all API tests |
npm run test:api |
Run API-specific tests only |
npm run test:db |
Verify JSON and Prisma DB connectivity |
npm run test:all |
Run all available tests |
npx prisma studio |
Launch the Prisma database GUI |
npx prisma db push |
Sync Prisma schema with the database |
npx prisma generate |
Regenerate Prisma client (after schema changes) |
./build_docker.sh |
Build the Docker container |
./run_docker.sh |
Run the Docker container |
9.5 Development Guidelines
- Variables:
varfor function scope,letfor block scope,constfor constants. - Modules: CommonJS (
require/module.exports). - Naming: camelCase for variables and functions; PascalCase for classes.
- Async: Prefer
async/awaitover callbacks. - Error handling:
try/catchblocks; log errors viamyUtils.log(error, logname). - Logging:
myUtils.log(data, globals.MODULE_LOG)for consistent module-level logging. - Database: Use the proxy pattern in
globals.persistentfor all database interactions. - Migrations: Always run
npx prisma generateafter changingprisma/schema.prisma. - Before pushing: Run
npm run test:all.
10. Tryon Versioning
Tryon app assets are versioned automatically whenever any file in globals.tryon_files changes.
10.1 How It Works
src/myUtils.jshashes all files listed inglobals.tryon_files.- The hash is compared against the stored
tryon_version_hashinvar/database/config.json. - If the hash differs: the version counter is incremented, and all tryon files are copied to
var/tryon_versions/v{N}/.
Each version directory contains: tryon.html, try-on.min.js, tryon_core.min.js, ML models, and all related static assets.
10.2 Version Configuration Keys (config.json)
| Key | Description |
|---|---|
tryon_version |
Auto-incremented version counter |
tryon_version_hash |
Hash of source files (change detection) |
stable_tryon_version |
Default version served to end users |
zara_tryon_version |
Version pinned for Zara |
ccc_tryon_version |
Version pinned for CCC |
inditex_mirror_tryon_version |
Version for Inditex mirror endpoints |
inditex_mobile_tryon_version |
Version for Inditex mobile endpoints |
10.3 Production Version History
| Version | Commit | Date | Notes |
|---|---|---|---|
| v477 | 98af1b6 |
2025-12-19 | Current stable. Updated masking model. Deployed to all Inditex endpoints 2025-12-22. |
| v469 | cdbf355 |
2025-12-03 | Used for Inditex mobile endpoints before v477. |
| v434 | 8cd795d |
2025-09-15 | Hotfix 5456687 applied 2025-10-16 (mask fading fix). Used for Inditex mirror before v477. |
10.4 Current Production Configuration (as of 2025-12-22)
| Client | Version |
|---|---|
stable_tryon_version |
v477 |
inditex_mirror_tryon_version |
v477 |
inditex_mobile_tryon_version |
v477 |
inditex_mirror_accessory_tryon_version |
v477 |
inditex_mobile_accessory_tryon_version |
v477 |
zara_tryon_version |
v229 |
ccc_tryon_version |
v196 |
10.5 Git Tags
Major releases are tagged for easy checkout:
11. Key Server-Side Libraries
| Library | Version | License | Purpose |
|---|---|---|---|
@google-cloud/storage |
7.0.1 | Apache-2.0 | Google Cloud Storage client |
@prisma/client |
5.22.0 | Apache-2.0 | Type-safe PostgreSQL database client |
@prisma/extension-accelerate |
3.0.1 | Apache-2.0 | Connection pooling and query caching |
express |
4.17.1 | MIT | Web application framework |
socket.io |
4.4.0 | MIT | Real-time bidirectional communication |
sharp |
0.33.4 | Apache-2.0 | High-performance server-side image processing |
multer |
1.4.5-lts.1 | MIT | Multipart/form-data file upload handling |
bcrypt |
5.0.0 | MIT | Password hashing |
canvas |
3.1.0 | MIT | Server-side canvas / image manipulation |
ejs |
3.1.6 | Apache-2.0 | Server-side HTML templating |
draco3dgltf |
1.5.5 | Apache-2.0 | 3D mesh compression (Draco) |
heic-convert |
1.2.4 | MIT | HEIC → JPEG/PNG conversion |
archiver |
5.3.0 | MIT | ZIP/TAR archive creation |
tar |
6.2.0 | ISC | TAR archive handling |
write-file-atomic |
3.0.3 | ISC | Atomic file writes |
node-cron |
3.0.0 | ISC | Cron-based task scheduling |
nodemailer |
6.7.2 | MIT | Email sending |
terser |
5.36.0 | BSD-2-Clause | JavaScript minification |
fs-extra |
9.1.0 | MIT | Enhanced Node.js filesystem methods |
compression |
1.7.4 | MIT | Express response compression middleware |
Client-Side Libraries (served from public/)
| Library | Purpose |
|---|---|
three.js |
3D scene rendering, OBJ/GLTF/USDZ loaders, shaders |
tensorflow.js |
In-browser ML inference (WebGL / CPU / WASM backends) |
onnx |
ONNX Runtime Web for cross-platform inference |
@litertjs/core + @litertjs/tfjs-interop |
LiteRT.js for .tflite inference via WebGPU/WASM |
12. Migration Roadmap (Express → Next.js)
The planned migration moves the web application and API from Express.js to a Next.js App Router architecture. External tools in scripts/ are out of scope.
Target Stack
| Component | Current | Target |
|---|---|---|
| Framework | Express.js | Next.js with App Router |
| Frontend | EJS templates + vanilla JS | React components |
| Styling | Custom CSS | Tailwind CSS |
| API | Express routes | Next.js API routes |
| Real-time | Socket.IO | Socket.IO with Next.js adapter |
| 3D (client) | Three.js | Three.js (retained) |
| Data Layer | Direct file operations | Abstracted data layer |
Migration Phases
Phase 1 — Project Setup: New Next.js project, TypeScript, Tailwind, ESLint/Prettier, environment variable migration, Express-to-App-Router endpoint mapping.
Phase 2 — Data Layer Abstraction: Storage adapter interfaces for local FS and GCS; data models with Zod/Yup validation; JSON-to-structured-storage ETL.
Phase 3 — API Route Migration: Port all Express route handlers to Next.js API routes; maintain backward compatibility during transition.
Phase 4 — Frontend Migration: Convert EJS templates to React; migrate wearfits-core.js, wearfits-editor.js, and admin views.
Phase 5 — Real-time & Workers: Adapt Socket.IO for Next.js; evaluate serverless compatibility of child-process workers.
Key Migration Considerations for Filesystem Operations
Files performing filesystem I/O that require special attention in a serverless/edge context:
| File | Operations |
|---|---|
src/init_fs_and_logging.js |
Directory creation, log stream setup |
src/myUtils.js |
Log management, archive handling, temp file cleanup |
src/myUtilsThreaded.js |
Full FS + GCS abstraction (primary I/O layer) |
src/photogrammetry_utils.js |
Archive extraction, image preprocessing |
router/assets.js |
Static file serving / cloud URL redirect |
- Move all server-only FS operations to API routes or server components.
- Isolate GCS operations from Edge Runtime (not compatible with the GCP SDK).
- The existing
myUtilsThreaded.jsabstraction layer should be preserved and adapted for Next.js constraints. - Audit
public/js/tryon_static_files.js— it contains hard-coded GCS URLs that will need refactoring.