Notification System
Run ID: 69b6ee7495d85cd597625a832026-03-29Development
PantheraHive BOS
BOS Dashboard

Workflow Execution Summary

The "Notification System" workflow (category: Development) has been successfully executed with the following user inputs:

This output provides a comprehensive plan for developing a robust, scalable, and user-centric notification system, specifically tailored for web applications, supporting both email and push notifications.

Notification System Overview

A modern notification system is crucial for engaging users, communicating important updates, and facilitating critical interactions. For a web platform, integrating email and push notifications requires a well-architected service that can reliably deliver messages, manage user preferences, and scale with demand.

The goal is to build a system that:

  1. Reliably delivers notifications across specified channels.
  2. Manages user preferences for notification types and frequency.
  3. Scales efficiently to handle varying message volumes.
  4. Provides real-time or near real-time updates for web users.
  5. Offers visibility and control over the notification process.

Core Components & Architecture (Web-Centric)

To support email, push notifications, and web integration, the system will comprise several decoupled components. This microservices-oriented approach enhances scalability, maintainability, and fault tolerance.

text • 10,752 chars
**Key Components:**

1.  **API Gateway / Notification API**:
    *   **Purpose**: Single entry point for all notification requests from internal services (e.g., user service, order service) or external systems.
    *   **Functionality**: Request validation, authentication, rate limiting, and routing to the Notification Service.
2.  **Notification Service**:
    *   **Purpose**: The central brain for processing, templating, and dispatching notifications.
    *   **Functionality**:
        *   Receives notification requests.
        *   Retrieves user preferences and notification templates.
        *   Composes notification messages.
        *   Publishes messages to the Message Queue for specific channel adapters.
        *   Manages notification history.
3.  **Message Queue (e.g., Kafka, RabbitMQ)**:
    *   **Purpose**: Decouples the Notification Service from channel-specific delivery, ensuring reliability and scalability.
    *   **Functionality**: Buffers messages, handles retries, and allows asynchronous processing.
4.  **Channel Adapters**:
    *   **Purpose**: Specialized services responsible for interacting with external channel providers.
    *   **Email Adapter**: Connects to an Email Service Provider (ESP) like SendGrid or Mailgun. Handles email formatting, sending, and bounce/delivery tracking.
    *   **Push Notification Adapter**: Connects to Firebase Cloud Messaging (FCM) for Android/Web push and Apple Push Notification service (APNs) for iOS. Manages device tokens, payload formatting, and sending.
5.  **Web Integration Module**:
    *   **Purpose**: Facilitates real-time, in-app notifications and potentially browser push notifications for the web client.
    *   **Functionality**:
        *   Consumes messages from the Message Queue relevant to web clients.
        *   Maintains WebSocket connections with active web clients to push real-time notifications.
        *   Manages browser push subscriptions (if enabled).
6.  **Database (PostgreSQL, MongoDB, etc.)**:
    *   **Purpose**: Stores all necessary data for the notification system.
    *   **Data**:
        *   **User Preferences**: Opt-in/out status per channel/type, frequency settings.
        *   **Notification Templates**: Reusable templates for different notification types.
        *   **Notification History**: Records of sent notifications, status, and timestamps.
        *   **Device Tokens**: For push notifications, linking users to their registered devices.
        *   **Audit Logs**: For debugging and compliance.
7.  **Caching Layer (e.g., Redis)**:
    *   **Purpose**: Improves performance by caching frequently accessed data like user preferences or templates.

## Implementation Strategy & Actionable Steps

### Phase 1: Foundation & Core Service

1.  **Define API Contracts**:
    *   Design RESTful API endpoints for the Notification API (e.g., `/notifications/send`, `/users/{id}/preferences`).
    *   Define JSON payload schemas for sending notifications (e.g., `type`, `userId`, `data`, `channels` array).
2.  **Database Schema Design**:
    *   Create tables for `users` (if not already existing), `user_preferences`, `notification_templates`, `notification_history`, and `device_tokens`.
    *   Ensure proper indexing for performance.
3.  **Implement Core Notification Service**:
    *   Develop the service to receive requests, fetch templates, apply personalization, and determine target channels based on user preferences.
    *   Integrate with the chosen Message Queue (producer side).
4.  **Set up Message Queue**:
    *   Provision and configure your chosen message queue (e.g., RabbitMQ, Kafka).
    *   Define topics/queues for different notification types or channels.

### Phase 2: Channel Integrations

1.  **Email Channel Integration**:
    *   **Select ESP**: Choose a reliable Email Service Provider (e.g., SendGrid, Mailgun, AWS SES).
    *   **Email Adapter Development**: Build a service that consumes email-specific messages from the Message Queue.
    *   **Template Management**: Implement logic to render HTML/plain text templates with dynamic data.
    *   **Unsubscribe Mechanisms**: Ensure compliance with CAN-SPAM/GDPR by including clear unsubscribe links and processing opt-out requests.
    *   **Delivery Tracking**: Integrate webhooks from the ESP to update notification history with delivery status (sent, opened, bounced).
2.  **Push Notification Channel Integration**:
    *   **FCM/APNs Integration**:
        *   Integrate with Firebase Cloud Messaging (FCM) for Android and Web Push.
        *   Integrate with Apple Push Notification service (APNs) for iOS.
    *   **Device Token Management**:
        *   Develop API endpoints for web clients to register and deregister device tokens.
        *   Store device tokens in the database, linked to user IDs.
        *   Implement logic to handle expired or invalid tokens (FCM/APNs feedback).
    *   **Push Adapter Development**: Build a service that consumes push-specific messages from the Message Queue, formats payloads for FCM/APNs, and sends them.
3.  **Web (In-app/Browser) Integration**:
    *   **WebSocket Server**: Implement a WebSocket server (e.g., using Socket.IO, native WebSockets) that the web client can connect to.
    *   **Web Integration Module**: This module consumes relevant messages from the Message Queue and pushes them to connected web clients via WebSockets.
    *   **Client-Side Implementation**:
        *   On the web client, implement WebSocket connection logic to receive real-time notifications.
        *   Display in-app notifications (e.g., toast messages, notification bell icon).
        *   **Optional: Browser Push Notifications**: Implement the Push API (Service Workers) to allow users to receive notifications even when the browser tab is closed. This requires handling user permission requests and managing subscription objects.

### Phase 3: User Management & Personalization

1.  **Preference Center**:
    *   Develop a user interface and corresponding API endpoints for users to manage their notification preferences.
    *   Allow users to:
        *   Opt-in/out of specific notification categories (e.g., marketing, transactional, security alerts).
        *   Choose preferred channels for different types (e.g., email for newsletters, push for urgent updates).
        *   Set frequency limits (e.g., daily digest for certain types).
2.  **Notification History**:
    *   Implement a section in the user's profile where they can view a history of all notifications received.

### Phase 4: Operational Readiness

1.  **Monitoring & Logging**:
    *   Instrument all services with logging (e.g., using ELK stack, Splunk, Datadog).
    *   Set up metrics collection (e.g., Prometheus, Grafana) for:
        *   Message queue depth.
        *   Notification send rates per channel.
        *   Delivery success/failure rates.
        *   Latency for each channel.
    *   Configure alerts for critical failures or performance degradations.
2.  **Error Handling & Retries**:
    *   Implement robust error handling for channel adapters (e.g., transient network issues).
    *   Configure dead-letter queues for messages that consistently fail to process.
3.  **Security Measures**:
    *   Encrypt sensitive data (e.g., device tokens, user IDs in logs) at rest and in transit.
    *   Secure API endpoints with appropriate authentication and authorization (e.g., OAuth2, API Keys).
    *   Implement rate limiting to prevent abuse.

## Specific Recommendations

### Technology Stack Recommendations

*   **Backend Services (Notification Service, Adapters)**:
    *   **Node.js (NestJS/Express)**: Excellent for I/O-bound tasks, strong ecosystem for WebSockets, and good for rapid development.
    *   **Python (Flask/FastAPI)**: Mature, great for data processing, and widely used.
*   **Database**:
    *   **PostgreSQL**: Robust, highly reliable, and supports complex queries and JSON data types.
*   **Message Queue**:
    *   **RabbitMQ**: Mature, robust, and excellent for complex routing and reliable delivery.
    *   **Apache Kafka**: Highly scalable, high-throughput, and durable, ideal for event streaming architectures.
*   **Email Service Provider (ESP)**:
    *   **SendGrid / Mailgun**: Industry-leading, provide excellent deliverability, analytics, and API features.
    *   **AWS SES**: Cost-effective for high volumes, requires more configuration.
*   **Push Notification Services**:
    *   **Firebase Cloud Messaging (FCM)**: Essential for Android and Web Push.
    *   **Apple Push Notification service (APNs)**: Essential for iOS.
*   **WebSockets**:
    *   **Socket.IO (Node.js)**: A popular library that provides real-time, bidirectional, event-based communication. Handles fallback mechanisms well.
    *   **Native WebSockets**: For more control and if specific library features are not needed.
*   **Caching**:
    *   **Redis**: In-memory data store, excellent for caching user preferences, device tokens, and rate limiting counters.

### Scalability & Reliability

*   **Microservices Architecture**: Decouple components to allow independent scaling and deployment.
*   **Idempotency**: Ensure that sending the same notification request multiple times does not result in duplicate messages being delivered.
*   **Dead-Letter Queues (DLQs)**: Configure DLQs for your message queue to capture messages that cannot be processed successfully, allowing for later inspection and reprocessing.
*   **Horizontal Scaling**: Design services to be stateless where possible, allowing easy horizontal scaling by adding more instances behind a load balancer.

### User Experience

*   **Clear Opt-in/Opt-out**: Provide transparent mechanisms for users to control their notifications.
*   **Frequency Capping**: Implement rules to prevent notification fatigue (e.g., no more than 3 notifications per hour from a specific category).
*   **Personalization**: Leverage user data (e.g., name, preferences, recent activity) to make notifications more relevant.
*   **Rich Notifications**: Utilize rich media (images, action buttons) where supported by channels (e.g., push notifications).

### Security

*   **API Key Management**: Securely manage API keys for external services (ESP, FCM, APNs) using environment variables or a secrets manager.
*   **Data Encryption**: Encrypt sensitive user data (e.g., email addresses, device tokens) in the database and during transit.
*   **Input Validation**: Thoroughly validate all incoming notification requests to prevent injection attacks or malformed data.

## Structured Data Examples

### Example `NotificationRequest` Payload (JSON)

This is the typical payload sent to the Notification API to trigger a notification.

Sandboxed live preview

Next Steps & Immediate Actions

  1. Team Alignment: Schedule a meeting with your development, product, and UX teams to review this architecture and align on requirements and priorities.
  2. Technology Selection: Finalize the specific technology stack (e.g., Python vs. Node.js, RabbitMQ vs. Kafka, SendGrid vs. Mailgun) based on your team's expertise, existing infrastructure, and project needs.
  3. Detailed Design: Begin with detailed architectural design for each component, including service contracts, data models, and deployment strategies.
  4. Proof-of-Concept (PoC): Start with a small PoC for one channel (e.g., email) to validate the core Notification Service and Message Queue integration.
  5. Security Review: Conduct an initial security review of the proposed architecture, focusing on data privacy, API authentication, and secrets management.
  6. Budgeting: Estimate costs for chosen third-party services (ESPs, Push services) and infrastructure.
notification_system.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);}});}