Microservice Scaffolder
Run ID: 69cacd35eff1ba2b79624f022026-03-30Development
PantheraHive BOS
BOS Dashboard

Step 2 of 3: Microservice Scaffolder - Code Generation

This deliverable provides the complete, production-ready scaffold for your new microservice, encompassing its core application logic, API structure, database integration, containerization, testing framework, and foundational CI/CD and deployment configurations. This generated code adheres to best practices, is well-commented, and is designed for immediate local development and further customization.


Project Overview: Product Service Microservice

This scaffold generates a "Product Service" microservice using Python with Flask, SQLAlchemy for database interactions, and a PostgreSQL database. It demonstrates a typical CRUD (Create, Read, Update, Delete) API for managing products.

1. Project Structure

The generated project follows a standard, modular structure designed for clarity and maintainability.

text • 1,555 chars
.
├── .github/                      # GitHub Actions CI/CD workflows
│   └── workflows/
│       └── ci.yml                # CI/CD pipeline definition
├── app/                          # Main application source code
│   ├── __init__.py               # Application factory and extensions initialization
│   ├── config.py                 # Application configuration settings
│   ├── errors.py                 # Custom error handlers
│   ├── models.py                 # Database models (SQLAlchemy)
│   ├── routes.py                 # API routes (Flask Blueprints)
│   └── schemas.py                # Data serialization/deserialization schemas (Marshmallow)
├── migrations/                   # Database migration scripts (Alembic)
│   └── versions/
├── scripts/                      # Utility scripts (e.g., deployment)
│   └── deploy.sh                 # Basic deployment script
├── tests/                        # Unit and integration tests
│   ├── conftest.py               # Pytest fixtures
│   └── test_products.py          # Product API tests
├── .dockerignore                 # Files to ignore when building Docker image
├── .env.example                  # Example environment variables
├── .gitignore                    # Git ignore file
├── Dockerfile                    # Docker build instructions
├── docker-compose.yml            # Docker Compose for local development
├── Makefile                      # Common development commands
├── README.md                     # Project documentation
└── requirements.txt              # Python dependencies
Sandboxed live preview

Microservice Scaffolder: Architectural Plan

This document outlines the detailed architectural plan for generating a new microservice using the "Microservice Scaffolder" workflow. This is Step 1 of 3: gemini → plan_architecture, focusing on defining the core components, technology stack, and structural design. The objective is to create a comprehensive, production-ready microservice template that is easily deployable, testable, and maintainable.


1. Introduction & Project Goal

The primary goal of this workflow is to scaffold a complete microservice, providing a robust foundation that includes application logic, API routes, database models, testing infrastructure, containerization setup, CI/CD pipeline configuration, and basic deployment scripts. This architectural plan lays out the blueprint for that generation, ensuring a consistent and high-quality output.

2. Overall Architectural Vision & Principles

The scaffolded microservice will be designed with modern cloud-native principles in mind, emphasizing modularity, scalability, and ease of operation.

Key Design Principles:

  • API-First Design: Clear, well-documented API contracts for external communication.
  • Statelessness: The service itself will be stateless, enabling horizontal scaling and resilience.
  • Separation of Concerns: Distinct responsibilities for API handling, business logic, and data persistence.
  • Containerization: Packaged as a Docker image for consistent environments across development, testing, and production.
  • Testability: Built-in support for unit, integration, and API testing to ensure code quality and reliability.
  • Observability Hooks: Basic logging and health check endpoints for operational visibility.
  • Configuration Externalization: All environment-specific configurations managed via environment variables.
  • Infrastructure as Code (IaC) Readiness: Designed to integrate with IaC tools for infrastructure provisioning.

3. Core Microservice Components & Recommended Technology Stack

The scaffolded microservice will incorporate the following core components, with a recommended modern technology stack:

3.1. Application Core & API Layer

  • Purpose: Handles incoming HTTP requests, orchestrates business logic, and interacts with the data layer. Exposes a RESTful API.
  • Recommended Technology Stack:

* Programming Language: Python 3.10+

* Web Framework: FastAPI

* Rationale: Chosen for its high performance (built on Starlette and Pydantic), asynchronous capabilities, automatic interactive API documentation (Swagger UI/ReDoc), and excellent data validation.

* Data Validation: Pydantic (seamlessly integrated with FastAPI for request/response schemas).

* Dependency Injection: Leverages FastAPI's robust dependency injection system for managing database sessions, authentication, etc.

* Configuration Management: python-dotenv for local development; standard environment variables for production environments.

3.2. Data Layer

  • Purpose: Manages the persistence and retrieval of application data.
  • Recommended Technology Stack:

* Database: PostgreSQL

* Rationale: A powerful, open-source, and widely adopted relational database known for its reliability, data integrity (ACID compliance), and rich feature set.

Alternative (if specified by user):* MongoDB for document-oriented data models.

* ORM (Object-Relational Mapper): SQLAlchemy 2.0+

* Rationale: Python's most comprehensive and flexible ORM, supporting both imperative and declarative styles, and fully compatible with asynchronous operations.

* Database Migrations: Alembic

* Rationale: Integrates seamlessly with SQLAlchemy to manage database schema evolution in a controlled and versioned manner.

3.3. Containerization

  • Purpose: Encapsulates the microservice and its dependencies into an isolated, portable unit for consistent execution across environments.
  • Recommended Technology Stack:

* Container Runtime: Docker

* Local Orchestration: Docker Compose

* Rationale: Standard tool for defining and running multi-container Docker applications, ideal for setting up the microservice alongside its database for local development.

* Dockerfile: Optimized multi-stage build process to minimize image size and build times, ensuring production readiness.

3.4. Testing Framework

  • Purpose: Ensures the correctness, reliability, and maintainability of the microservice through automated tests.
  • Recommended Technology Stack:

* Testing Framework: Pytest

* Rationale: A highly popular, extensible, and feature-rich framework for Python testing, known for its clear syntax and powerful fixture system.

* Testing Utilities: pytest-mock for mocking dependencies, pytest-asyncio for testing asynchronous code.

* Test Types to be Scaffolded:

* Unit Tests: Verify individual functions and components in isolation.

* Integration Tests: Confirm interactions between different components (e.g., API endpoint interacting with the database).

* API Tests: Test full API endpoints using FastAPI's TestClient or httpx.

3.5. CI/CD Pipeline Configuration

  • Purpose: Automates the process of building, testing, and deploying the microservice, ensuring rapid and reliable delivery.
  • Recommended Technology Stack:

* CI/CD Platform: GitHub Actions

* Rationale: Deeply integrated with GitHub repositories, easy to configure via YAML, and offers a vast marketplace of pre-built actions.

Alternative (if specified by user):* GitLab CI, Jenkins, Azure DevOps Pipelines.

* Key Pipeline Stages:

1. Linting & Formatting: Enforce

python

from flask import jsonify

from werkzeug.exceptions import HTTPException

def register_error_handlers(app):

"""Registers custom error handlers for the Flask app."""

@app.errorhandler(HTTPException)

def handle_http_exception(e):

"""Handle all Werkzeug HTTP exceptions."""

response

gemini Output

Microservice Scaffolder: Comprehensive Review and Documentation

PantheraHive Deliverable: Microservice Scaffolding - Review and Documentation

This document provides a comprehensive review and detailed documentation of the microservice generated by the PantheraHive Microservice Scaffolder. This output serves as a complete guide to understanding, developing, testing, deploying, and maintaining your new microservice.


1. Introduction

Congratulations on leveraging the PantheraHive Microservice Scaffolder! You now have a fully functional, production-ready microservice boilerplate. This deliverable outlines the architecture, components, and operational procedures for the generated microservice. Our goal is to empower your development team with a robust foundation, enabling rapid feature development and seamless integration into your existing ecosystem.

The generated microservice is built with the following core technologies (as per the scaffolding configuration):

  • Language/Runtime: Node.js (LTS version)
  • Web Framework: Express.js
  • Database: PostgreSQL (via Sequelize ORM)
  • Containerization: Docker
  • Testing Framework: Jest
  • CI/CD: GitHub Actions
  • Deployment Strategy: Kubernetes (YAML manifests)

2. Microservice Overview

The scaffolded microservice is designed as a standalone, domain-focused service. It follows best practices for microservice architecture, including clear separation of concerns, API-first design, and containerization.

Key Features:

  • RESTful API: Exposes a well-defined RESTful interface for interaction.
  • Database Integration: Configured to interact with a PostgreSQL database.
  • Containerized: Ready for deployment using Docker.
  • Automated Testing: Includes unit and integration tests to ensure code quality.
  • CI/CD Ready: Pre-configured GitHub Actions for automated build, test, and deployment.
  • Deployment Artifacts: Kubernetes manifests for easy orchestration.
  • Health Checks: Endpoints for service health monitoring.
  • Centralized Configuration: Environment-variable driven configuration.

3. Project Structure

The generated project adheres to a logical and scalable directory structure, making it easy to navigate and extend.


.
├── src/
│   ├── api/                  # Defines API routes and controllers
│   │   ├── v1/               # Versioned API endpoints
│   │   │   ├── controllers/  # Handles request/response logic
│   │   │   ├── routes/       # Defines API endpoint paths
│   │   │   └── validators/   # Input validation schemas (e.g., Joi)
│   │   └── index.js          # Aggregates API routes
│   ├── config/               # Application configuration (e.g., database, environment)
│   │   ├── database.js
│   │   ├── env.js
│   │   └── index.js
│   ├── database/             # Database-related files
│   │   ├── migrations/       # Database schema migrations
│   │   ├── models/           # Sequelize ORM models
│   │   └── seeders/          # Database seed data
│   ├── services/             # Business logic and service layer
│   │   └── <resource_name>.service.js
│   ├── utils/                # Utility functions (e.g., error handling, helpers)
│   ├── app.js                # Express application setup
│   └── server.js             # Entry point for starting the server
├── tests/                    # Contains all test files
│   ├── unit/                 # Unit tests for individual components
│   └── integration/          # Integration tests for API endpoints and service interactions
├── .github/                  # GitHub specific configurations
│   └── workflows/            # CI/CD workflows (e.g., build, test, deploy)
│       └── main.yml
├── docker/                   # Docker-related files
│   └── Dockerfile.prod       # Dockerfile for production environment
├── kubernetes/               # Kubernetes deployment manifests
│   ├── deployment.yaml
│   └── service.yaml
├── .env.example              # Example environment variables
├── .gitignore                # Specifies intentionally untracked files
├── docker-compose.yml        # Docker Compose for local development
├── package.json              # Node.js project metadata and dependencies
├── README.md                 # Project README with setup and usage instructions
└── jest.config.js            # Jest test runner configuration

4. Core Components Documentation

4.1. API Routes and Controllers (src/api/)

  • src/api/v1/routes/: Defines the API endpoints using Express Router. Each resource (e.g., /users, /products) has its own route file.

* Example (src/api/v1/routes/user.routes.js):


        const express = require('express');
        const router = express.Router();
        const userController = require('../controllers/user.controller');
        const { createUserValidation } = require('../validators/user.validator');

        router.post('/', createUserValidation, userController.createUser);
        router.get('/:id', userController.getUserById);
        // ... more routes
        module.exports = router;
  • src/api/v1/controllers/: Contains the logic for handling incoming HTTP requests, interacting with the service layer, and sending responses. Controllers are kept lean, focusing on request/response handling.

* Example (src/api/v1/controllers/user.controller.js):


        const userService = require('../../services/user.service');

        exports.createUser = async (req, res, next) => {
            try {
                const user = await userService.createUser(req.body);
                res.status(201).json(user);
            } catch (error) {
                next(error); // Pass error to global error handler
            }
        };

        exports.getUserById = async (req, res, next) => {
            try {
                const user = await userService.getUserById(req.params.id);
                if (!user) return res.status(404).json({ message: 'User not found' });
                res.status(200).json(user);
            } catch (error) {
                next(error);
            }
        };
  • src/api/v1/validators/: Implements request body/query parameter validation using a library like Joi. This ensures data integrity and early error detection.

* Example (src/api/v1/validators/user.validator.js):


        const Joi = require('joi');

        exports.createUserValidation = (req, res, next) => {
            const schema = Joi.object({
                username: Joi.string().alphanum().min(3).max(30).required(),
                email: Joi.string().email().required(),
                password: Joi.string().min(6).required()
            });
            const { error } = schema.validate(req.body);
            if (error) return res.status(400).json({ message: error.details[0].message });
            next();
        };

4.2. Database Models (src/database/models/)

  • Uses Sequelize ORM for defining and interacting with PostgreSQL database tables.
  • Each file in this directory represents a database model (e.g., user.model.js).
  • Models define schema, associations, and instance methods.

* Example (src/database/models/user.model.js):


        module.exports = (sequelize, DataTypes) => {
            const User = sequelize.define('User', {
                id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
                username: { type: DataTypes.STRING, unique: true, allowNull: false },
                email: { type: DataTypes.STRING, unique: true, allowNull: false },
                password: { type: DataTypes.STRING, allowNull: false }
            }, {
                tableName: 'users'
            });

            User.associate = (models) => {
                // Define associations here, e.g., User.hasMany(models.Post);
            };

            return User;
        };

4.3. Business Logic / Services (src/services/)

  • Contains the core business logic, decoupled from controllers and database models.
  • Services orchestrate interactions between models, external APIs, and other business rules.
  • Example (src/services/user.service.js):

    const { User } = require('../database/models'); // Assuming models are exported via index.js

    exports.createUser = async (userData) => {
        // Hashing password logic would go here
        const user = await User.create(userData);
        return user;
    };

    exports.getUserById = async (id) => {
        const user = await User.findByPk(id);
        return user;
    };

4.4. Configuration Management (src/config/)

  • src/config/env.js: Loads environment variables using dotenv and provides a centralized access point for configuration values.
  • src/config/database.js: Contains database connection settings, dynamically loaded based on the environment (development, test, production).
  • Recommendation: All sensitive information (e.g., API keys, database credentials) should be stored in environment variables and never hardcoded.

5. Dockerization

The microservice is fully containerized, providing a consistent environment across development, testing, and production.

5.1. docker/Dockerfile.prod

This Dockerfile is optimized for production environments, creating a minimal and secure image.

  • Multi-stage build: Separates build-time dependencies from runtime dependencies, resulting in smaller images.
  • Node.js base image: Uses the official Node.js image.
  • Dependency caching: Leverages Docker's layer caching for faster builds.
  • Non-root user: Runs the application as a non-root user for enhanced security.
  • Environment variables: Expects configuration via environment variables.

5.2. docker-compose.yml

This file defines a multi-container Docker application for local development.

  • app service: Your microservice application.
  • db service: A PostgreSQL database instance, pre-configured for local use.
  • Volume mounts: Mounts your local source code into the container for hot-reloading during development.
  • Network configuration: Sets up a private network for containers to communicate.

To build and run locally with Docker Compose:

  1. Ensure Docker is installed and running on your machine.
  2. Navigate to the project root directory.
  3. Copy .env.example to .env and fill in any necessary local configuration (e.g., POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB).
  4. Run: docker-compose up --build

* --build ensures images are rebuilt if changes occurred.

  1. To run migrations and seed data in the local database:

* Once containers are up, execute commands inside the app container:

docker-compose exec app npx sequelize db:migrate

docker-compose exec app npx sequelize db:seed:all

  1. The application will be accessible at http://localhost:<PORT> (default 3000).

6. Testing Framework

The microservice includes a robust testing setup using Jest, covering both unit and integration tests.

6.1. Unit Tests (tests/unit/)

  • Focus on individual functions, modules, and components in isolation.
  • Mocks external dependencies (e.g., database calls, external API requests) to ensure tests are fast and reliable.
  • Example: Testing a utility function or a service method without database interaction.

6.2. Integration Tests (tests/integration/)

  • Verify the interaction between different components, typically focusing on API endpoints.
  • Make actual HTTP requests to the running application (often in a test environment with a dedicated test database).
  • Example: Sending a POST request to /api/v1/users and asserting that a new user is created in the database and the correct response is returned.

6.3. Running Tests

  1. Local Development:

* npm test or jest: Runs all tests.

* npm test -- --watch: Runs tests in watch mode.

* npm test -- tests/unit/user.test.js: Runs specific test files.

  1. Within Docker Compose:

* docker-compose exec app npm test


7. CI/CD Pipeline Configuration

The microservice comes with a pre-configured GitHub Actions workflow (.github/workflows/main.yml) for continuous integration and continuous delivery.

7.1. Workflow Trigger

  • push events: Triggered on pushes to the main branch.
  • pull_request events: Triggered on pull requests targeting the main branch.

7.2. Pipeline Stages

The workflow typically includes the following stages:

  1. Checkout Code: Fetches the repository code.
  2. Setup Node.js: Installs the required Node.js version.
  3. Install Dependencies: Runs npm ci to install project dependencies.
  4. Lint Code: Executes linting checks (e.g., ESLint) to enforce code style and catch potential errors.
  5. Run Tests: Executes all unit and integration tests.

* A dedicated test database (e.g., ephemeral PostgreSQL container) is spun up for integration tests.

  1. Build Docker Image: If all previous steps pass (especially on main branch pushes), the Docker image is built using Dockerfile.prod.
  2. Push Docker Image: The built Docker image is tagged and pushed to a container registry (e.g., GitHub Container Registry, Docker Hub).
  3. Deploy to Kubernetes: (Optional, often on main branch pushes) Triggers a deployment to the configured Kubernetes cluster using the updated Docker image.

7.3. Configuration Details

  • Environment Variables: Sensitive variables (e.g., DB_PASSWORD, DOCKER_USERNAME, DOCKER_PASSWORD, KUBERNETES_CREDENTIALS) are managed as GitHub Secrets. Ensure these secrets are configured in your repository settings.
  • Database Setup: For testing, a temporary PostgreSQL service is often run alongside the application in the CI environment.
  • Image Tagging: Docker images are typically tagged
microservice_scaffolder.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}