diff --git a/docs/teams/fullstack/appendices/00_glossary.md b/docs/teams/fullstack/appendices/00_glossary.md index 0f5336d9..5593efde 100644 --- a/docs/teams/fullstack/appendices/00_glossary.md +++ b/docs/teams/fullstack/appendices/00_glossary.md @@ -9,15 +9,21 @@ The server-side part of an application responsible for business logic, database **Caching** The process of storing frequently accessed data in memory to improve performance and reduce database load (e.g., using Redis or Memcached). -**CI (Continuous Integration)** -A practice where code changes are automatically built and tested to detect issues early in the development cycle. - **CD (Continuous Deployment/Delivery)** Automated processes for deploying code to production or staging environments after passing automated tests. +**CI (Continuous Integration)** +A practice where code changes are automatically built and tested to detect issues early in the development cycle. + **CMS (Content Management System)** Software that allows users to create, manage, and modify website content without needing to code. +**Composable** +A reusable function in Vue 3's Composition API that encapsulates and shares stateful logic across components. Composables follow the `use` prefix convention (e.g., `useUser`, `useFetch`). + +**Container Orchestration** +The automated management of containerized applications, including deployment, scaling, networking, and health monitoring. Tools include Docker Compose (for development) and Google Cloud Run (for production). + **CSS (Cascading Style Sheets)** A language used to describe the presentation and layout of web pages. @@ -36,6 +42,9 @@ A major update to JavaScript that introduced new syntax and features, making the **DOM (Document Object Model)** A programming interface that represents the structure of HTML or XML documents as a tree of objects, allowing scripts to update content, structure, and style. +**E2E (End-to-End) Testing** +A testing methodology that validates the entire application flow from the user's perspective, simulating real user interactions through a browser or API client. + **Frontend** The client-side part of an application that users interact with directly, typically built with HTML, CSS, and JavaScript. @@ -51,9 +60,15 @@ The standard language for creating web pages and web applications. **HTTP/HTTPS (HyperText Transfer Protocol / Secure)** Protocols for transferring data over the web; HTTPS adds encryption for security. +**IaC (Infrastructure as Code)** +The practice of managing and provisioning infrastructure through machine-readable configuration files (e.g., Terraform, Pulumi) rather than manual processes. + **IDE (Integrated Development Environment)** Software that provides comprehensive tools for software development, such as code editing, debugging, and testing. +**Jest** +A JavaScript and TypeScript testing framework with built-in assertion library, mocking, and code coverage. Used as our standard testing tool for both backend (NestJS) and frontend (Vue) projects. + **JSON (JavaScript Object Notation)** A lightweight data-interchange format, easy for humans to read and write, and easy for machines to parse and generate. @@ -63,15 +78,24 @@ A programming language used to create dynamic and interactive effects within web **JWT (JSON Web Token)** A compact, URL-safe token format used for securely transmitting information between parties, commonly used for authentication and authorization. +**LLM (Large Language Model)** +An AI model trained on large amounts of text data, capable of generating and understanding natural language. Used in development tools like GitHub Copilot, Claude, and ChatGPT. + **Load Balancer** A system that distributes incoming network traffic across multiple servers to ensure reliability and scalability. **Middleware** Software that acts as a bridge between different systems or layers, commonly used in web frameworks to process requests and responses. +**Monorepo** +A software development strategy where code for multiple projects or packages is stored in a single repository, enabling shared tooling and easier cross-project changes. + **NoSQL** A category of database systems that store and retrieve data in formats other than relational tables, such as key-value, document, columnar, or graph formats. Popular NoSQL databases include MongoDB, Cassandra, and Redis. +**OpenAPI (Swagger)** +A specification for describing RESTful APIs in a machine-readable format, enabling automatic documentation generation, client SDK generation, and API testing. + **ORM (Object-Relational Mapping)** A programming technique for converting data between incompatible type systems in object-oriented programming languages. It allows developers to interact with a database using objects instead of SQL queries. @@ -90,13 +114,15 @@ A software distribution model in which applications are hosted by a provider and **SPA (Single Page Application)** A web application that loads a single HTML page and dynamically updates content as the user interacts with the app. +**SSR (Server-Side Rendering)** +A technique where web pages are rendered on the server and sent as fully formed HTML to the client, improving initial load performance and SEO. + **SQL (Structured Query Language)** A standard language for managing and manipulating relational databases. **TypeScript** A strongly-typed superset of JavaScript that adds static typing, interfaces, and other features to improve code quality and maintainability, commonly used in both frontend and backend (Node.js) development. - **UI (User Interface)** The visual elements of an application that users interact with. diff --git a/docs/teams/fullstack/appendices/10_scripts.md b/docs/teams/fullstack/appendices/10_scripts.md index 0028bb2f..af9dd922 100644 --- a/docs/teams/fullstack/appendices/10_scripts.md +++ b/docs/teams/fullstack/appendices/10_scripts.md @@ -1,2 +1,165 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Useful Scripts & Tools + +A collection of commonly used scripts and commands for day-to-day development work. + +## Database Scripts + +### Reset Local Database + +Drops and recreates the database, runs migrations, and seeds development data: + +```bash +#!/bin/bash +# scripts/db-reset.sh + +echo "Dropping and recreating database..." +docker compose exec postgres psql -U myuser -c "DROP DATABASE IF EXISTS mydb;" +docker compose exec postgres psql -U myuser -c "CREATE DATABASE mydb;" + +echo "Running migrations..." +docker compose exec api npm run migrate + +echo "Seeding development data..." +docker compose exec api npm run seed + +echo "Database reset complete." +``` + +### Database Dump and Restore + +```bash +# Export a database dump +docker compose exec -T postgres pg_dump -U myuser mydb > backup.sql + +# Import a database dump +docker compose exec -T postgres psql -U myuser mydb < backup.sql +``` + +### Quick Migration Commands + +```bash +# Prisma +docker compose exec api npx prisma migrate dev --name description_of_change +docker compose exec api npx prisma generate +docker compose exec api npx prisma studio # Visual database browser + +# TypeORM +docker compose exec api npx typeorm migration:generate -n MigrationName +docker compose exec api npx typeorm migration:run +docker compose exec api npx typeorm migration:revert +``` + +## Docker Scripts + +### Clean Rebuild + +When things are broken and you want a fresh start: + +```bash +# Stop everything, remove volumes, rebuild +docker compose down -v +docker compose build --no-cache +docker compose up -d +``` + +### View Logs + +```bash +# Follow all logs +docker compose logs -f + +# Follow a specific service +docker compose logs -f api + +# Show last 100 lines +docker compose logs --tail=100 api +``` + +### Shell Access + +```bash +# Open a shell in the API container +docker compose exec api sh + +# Run a one-off command +docker compose exec api npm run lint +``` + +## Development Helpers + +### Generate NestJS Resources + +```bash +# Generate a complete CRUD module +npx nest generate resource users + +# Generate individual components +npx nest generate module users +npx nest generate service users +npx nest generate controller users +``` + +### Quick Dependency Check + +```bash +# Check for outdated packages +npm outdated + +# Check for security vulnerabilities +npm audit + +# Update all packages to latest within semver range +npm update +``` + +### TypeScript Type Checking + +```bash +# Run type checker without emitting files +npx tsc --noEmit + +# Watch mode for continuous type checking +npx tsc --noEmit --watch +``` + +## Git Helpers + +### Clean Up Local Branches + +```bash +# Delete all local branches that have been merged to develop +git branch --merged develop | grep -v "develop\|main" | xargs git branch -d + +# Prune remote tracking branches that no longer exist +git remote prune origin +``` + +### Quick Rebase on Develop + +```bash +git fetch origin +git rebase origin/develop +``` + +## npm Scripts Convention + +Every project should define these scripts in `package.json`: + +```json +{ + "scripts": { + "dev": "nest start --watch", + "build": "nest build", + "start": "node dist/main.js", + "lint": "eslint . --fix", + "format": "prettier --write .", + "test": "jest", + "test:watch": "jest --watch", + "test:e2e": "jest --config jest.e2e.config.ts", + "migrate": "prisma migrate deploy", + "migrate:dev": "prisma migrate dev", + "seed": "ts-node prisma/seed.ts", + "type-check": "tsc --noEmit" + } +} +``` diff --git a/docs/teams/fullstack/appendices/20_faq.md b/docs/teams/fullstack/appendices/20_faq.md index 0028bb2f..14bbce4d 100644 --- a/docs/teams/fullstack/appendices/20_faq.md +++ b/docs/teams/fullstack/appendices/20_faq.md @@ -1,2 +1,129 @@ -!!! warning "Work in progress" - \ No newline at end of file +# FAQ + +Answers to common questions from new team members and recurring topics. + +## Onboarding + +### How do I get access to the project repositories? + +Ask your team lead to add you to the [Futured GitHub organization](https://github.com/futuredapp). You'll need a GitHub account. Once added, you'll have access to all team repositories. + +### How do I set up my local environment? + +Follow the [Local Setup Instructions](../dev_env/00_local_setup.md). In short: + +1. Install Node.js (via nvm), Docker Desktop (or OrbStack on Mac), and Git +2. Clone the repository +3. Copy `docker-compose.dist.yml` to `docker-compose.yml` and fill in the values +4. Run `docker compose up -d` +5. Run migrations and seed data + +### Where do I find the environment variables? + +Ask your team lead or a colleague working on the project. Credentials are shared securely (not via Slack/email). See [Secrets Management](../dev_env/10_secrets.md) for the full process. + +### Which IDE should I use? + +We don't mandate a specific IDE. Most team members use: + +- **WebStorm** (JetBrains) — Full-featured, excellent TypeScript/Vue support +- **VS Code** — Lightweight, great with extensions +- **Cursor** — VS Code fork with built-in AI features + +Whatever you use, make sure ESLint and Prettier are configured to run on save. + +## Development + +### REST or GraphQL — which should I use? + +See the [Backend](../tech_stack/10_backend.md) page for a comparison table. In short: + +- **REST** for simple CRUD, public APIs, file operations, webhooks +- **GraphQL** for complex data relationships, flexible frontend queries, real-time subscriptions + +Most projects start with REST. Use GraphQL when the frontend needs outgrow simple endpoints. + +### How do I create a new feature branch? + +```bash +git checkout develop +git pull origin develop +git checkout -b feature/ABC-123-short-description +``` + +See [Git Flow](../development/00_git_flow.md) for the full branching model. + +### How do I handle database schema changes? + +Always use migrations. Never modify the database schema manually. See the migration sections in [Database](../tech_stack/20_database.md) and [Deployment](../deployment/00_deployment.md). + +### Why do we use Docker for local development? + +Docker ensures everyone runs the same environment regardless of their OS. It eliminates "works on my machine" issues, makes onboarding faster, and keeps dependencies (PostgreSQL, Redis, etc.) isolated from your system. + +### How do I add a new npm package? + +```bash +# npm +npm install package-name # production dependency +npm install -D package-name # development dependency + +# yarn +yarn add package-name # production dependency +yarn add -D package-name # development dependency +``` + +Before adding a package, check: + +- Is it actively maintained? +- Does it have TypeScript types? +- Does it add significant bundle size? (check on [bundlephobia.com](https://bundlephobia.com)) +- Is there already a similar package in the project? + +## Code Review + +### How quickly should I review a PR? + +Aim to start a review within the same business day. If you can't review in time, let the author know so they can find another reviewer. + +### What should I focus on during code review? + +1. **Correctness** — Does the code do what it's supposed to? +2. **Security** — Are there any vulnerabilities (SQL injection, XSS, exposed secrets)? +3. **Architecture** — Does it fit the project structure? Is it in the right module? +4. **Edge cases** — What happens with empty input, null values, concurrent requests? +5. **Tests** — Are critical paths tested? + +See [Code Review Process](../development/20_code_review_process.md) for the full guidelines. + +### Can I use AI tools for code review? + +Yes. We use Copilot and CodeRabbit for automated analysis. They catch common issues and provide suggestions. However, AI review supplements — it doesn't replace — human review. Always verify AI suggestions against the project context. + +## Deployment + +### How do I deploy to the dev environment? + +Merge your PR to `develop`. The CI/CD pipeline will automatically build and deploy. + +### How do I deploy to production? + +Create a PR from `develop` to `main`. After approval and merge, the pipeline deploys automatically. See [Deployment Process](../deployment/00_deployment.md). + +### What do I do if a deployment breaks production? + +Follow the [Rollback Procedures](../deployment/10_rollback.md). The quickest fix is usually redeploying the previous container image. + +## Architecture Decisions + +### Why NestJS instead of Express? + +NestJS provides structure, dependency injection, and modularity out of the box. Express gives you freedom but requires you to build all of that yourself. For team projects, the consistency of NestJS saves more time than the flexibility of Express. + +### Why Vue instead of React? + +Vue was adopted as our primary frontend framework based on team experience and project needs. Vue's Composition API + TypeScript provides an excellent developer experience. For projects where React is a better fit (e.g., client requirement, React Native), we use React. + +### Why PostgreSQL as the default database? + +PostgreSQL offers the best balance of reliability, features, and performance for our typical use cases (transactional web applications). It handles JSON data well enough to cover most semi-structured data needs too. diff --git a/docs/teams/fullstack/appendices/30_templates.md b/docs/teams/fullstack/appendices/30_templates.md index 0028bb2f..adc53065 100644 --- a/docs/teams/fullstack/appendices/30_templates.md +++ b/docs/teams/fullstack/appendices/30_templates.md @@ -1,2 +1,136 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Templates + +Reusable templates for common documents and processes. + +## Pull Request Template + +Save as `.github/pull_request_template.md` in your repository: + +```markdown +## Description + + + +[ABC-123](https://futured.atlassian.net/browse/ABC-123) + +## Changes + +- + +## How to Test + + + +1. + +## Checklist + +- [ ] Self-reviewed on GitHub +- [ ] CI checks pass +- [ ] Tests added/updated for new functionality +- [ ] No secrets or credentials committed +``` + +## Project README Template + +```markdown +# Project Name + +Brief description of what this project does. + +## Tech Stack + +- **Backend**: NestJS, TypeScript, PostgreSQL +- **Frontend**: Vue 3 / Nuxt 3, TypeScript +- **Infrastructure**: Docker, GitHub Actions, GCP / Digital Ocean + +## Quick Start + +### Prerequisites + +- Node.js (see `.nvmrc`) +- Docker Desktop or OrbStack + +### Setup + +1. Clone the repository +2. `cp docker-compose.dist.yml docker-compose.yml` +3. Fill in environment variables (ask a team member for values) +4. `docker compose up -d` +5. `docker compose exec api npm run migrate` +6. `docker compose exec api npm run seed` + +### Development + +- **API**: http://localhost:8080 +- **Frontend**: http://localhost:3000 +- **API docs**: http://localhost:8080/api/docs + +### Scripts + +| Script | Description | +|---|---| +| `npm run dev` | Start dev server with hot reload | +| `npm run build` | Build for production | +| `npm run test` | Run tests | +| `npm run lint` | Lint and format | + +## Environment Variables + +| Variable | Description | Required | +|---|---|---| +| `DATABASE_URL` | PostgreSQL connection string | Yes | +| `JWT_SECRET` | Secret for signing tokens | Yes | + +## Deployment + +Deployed via GitHub Actions. See `.github/workflows/` for pipeline configuration. + +- **Dev**: Deploys on merge to `develop` +- **Production**: Deploys on merge to `main` +``` + +## Docker Compose Template + +Starting point for new project infrastructure: + +```yaml +# docker-compose.dist.yml +services: + api: + build: + context: . + dockerfile: dev.Dockerfile + ports: + - "8080:8080" + volumes: + - ./src:/app/src + environment: + NODE_ENV: development + DATABASE_URL: postgresql://myapp:localdev@postgres:5432/myapp + JWT_SECRET: local-dev-secret-change-in-production + REDIS_HOST: cache + REDIS_PORT: 6379 + depends_on: + - postgres + - cache + + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: myapp + POSTGRES_USER: myapp + POSTGRES_PASSWORD: localdev + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + + cache: + image: redis:7-alpine + ports: + - "6379:6379" + +volumes: + pgdata: +``` diff --git a/docs/teams/fullstack/coding_standards/00_style_guides.md b/docs/teams/fullstack/coding_standards/00_style_guides.md index 7db5bc3a..32c37d7b 100644 --- a/docs/teams/fullstack/coding_standards/00_style_guides.md +++ b/docs/teams/fullstack/coding_standards/00_style_guides.md @@ -93,12 +93,35 @@ async getUsers(): Promise { … } #### 4. **Vue.js with TypeScript** -- **Use ` +``` + +- **Use composables for reusable logic** ```typescript -props: { - userId: { type: String as PropType, required: true } +// composables/useUser.ts +export function useUser(userId: string) { + const user = ref(null) + const loading = ref(false) + + async function fetchUser() { + loading.value = true + user.value = await userApi.getById(userId) + loading.value = false + } + + return { user, loading, fetchUser } } ``` diff --git a/docs/teams/fullstack/coding_standards/10_linting.md b/docs/teams/fullstack/coding_standards/10_linting.md index 9cc47694..c8c66c9a 100644 --- a/docs/teams/fullstack/coding_standards/10_linting.md +++ b/docs/teams/fullstack/coding_standards/10_linting.md @@ -3,7 +3,7 @@ We enforce consistent code quality and style across all our projects by using a shared set of linting rules, maintained in our public repository: [https://github.com/futuredapp/eslint-config-futured](https://github.com/futuredapp/eslint-config-futured) -Each project imports the appropriate linting configuration from this repository via npm, ensuring that all developers follow the same standards—whether working on frontend (Vue.js) or backend (NestJS) code. +Each project imports the appropriate linting configuration from this repository via npm/yarn, ensuring that all developers follow the same standards—whether working on frontend (Vue.js) or backend (NestJS) code. In the future, we will also include Prettier rules in this shared configuration for automated code formatting. @@ -33,9 +33,12 @@ Linting is the process of automatically analyzing code to detect errors, enforce - **ESLint** Our primary linting tool for both JavaScript and TypeScript, with custom rule sets for Vue.js (frontend) and NestJS (backend). - **Prettier** - Soon to be included in our shared configuration for automated code formatting, ensuring consistent style across all projects. + Included in our shared configuration for automated code formatting, ensuring consistent style across all projects. Prettier handles all formatting concerns (indentation, line length, trailing commas, etc.) so ESLint can focus on code quality rules. - **Editor Integration** - We encourage developers to set up linting and formatting to run automatically in their code editors for real-time feedback and corrections. We have a guide for automating this setup in out internal documentation. + We encourage developers to set up linting and formatting to run automatically in their code editors for real-time feedback and corrections. We have a guide for automating this setup in our internal documentation. + +!!! info "Evolving Tooling" + The JavaScript/TypeScript linting ecosystem is evolving rapidly. While ESLint with our shared config remains our standard, we keep an eye on emerging tools like ESLint flat config and Biome. Any tooling changes will be evaluated for compatibility with our existing workflows and adopted incrementally. --- diff --git a/docs/teams/fullstack/coding_standards/30_testing.md b/docs/teams/fullstack/coding_standards/30_testing.md index 0028bb2f..e7b7216b 100644 --- a/docs/teams/fullstack/coding_standards/30_testing.md +++ b/docs/teams/fullstack/coding_standards/30_testing.md @@ -1,2 +1,193 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Testing Standards + +This guide covers our testing philosophy, tooling, and conventions for full-stack projects. + +!!! warning "Current State" + + Testing is **not consistent** across projects. Some projects have solid test suites, others have minimal or no tests. This section defines what we aspire to and the minimum requirements we are working towards. Frontend testing in particular lags behind backend — there is no established equivalent of testing against a design (e.g. visual regression against Figma), though this is an area we want to explore. + +## Minimum Requirements + +Every project **must** have at minimum: + +- **Backend**: Integration tests for authentication flows and critical business logic (payments, data mutations) +- **CI gate**: Tests run on every PR — failing tests block the merge +- **Bug fixes**: A regression test accompanying every bug fix + +Everything beyond this is strongly encouraged but depends on the project's scope and timeline. + +## Testing Philosophy + +- **Test behavior, not implementation** — tests should verify what the code does, not how it does it +- **Prefer integration tests** over unit tests for backend services — they catch more real bugs with less maintenance +- **Every bug fix includes a test** — reproduce the bug with a failing test before fixing it +- **Tests are documentation** — well-named tests explain the expected behavior of the system + +## Testing Pyramid + +``` + ┌─────────┐ + │ E2E │ Few, slow, high confidence + ├─────────┤ + │ Integr. │ Moderate count, test real interactions + ├─────────┤ + │ Unit │ Many, fast, focused on logic + └─────────┘ +``` + +| Layer | What it tests | Tools | Speed | +|---|---|---|---| +| Unit | Pure functions, utilities, isolated logic | Jest | Fast | +| Integration | Service methods with database, API endpoints | Jest + test DB | Medium | +| E2E | Full user flows through the browser or API | Playwright / Cypress | Slow | + +## Backend Testing + +### Unit Tests + +Use for pure business logic, utility functions, and DTOs: + +```typescript +// users.service.spec.ts +describe('UsersService', () => { + describe('validateEmail', () => { + it('should accept valid email addresses', () => { + expect(validateEmail('user@example.com')).toBe(true) + }) + + it('should reject invalid email addresses', () => { + expect(validateEmail('not-an-email')).toBe(false) + }) + }) +}) +``` + +### Integration Tests + +Test NestJS modules with real database connections: + +```typescript +// users.service.integration.spec.ts +describe('UsersService (integration)', () => { + let service: UsersService + let module: TestingModule + + beforeAll(async () => { + module = await Test.createTestingModule({ + imports: [AppModule], + }).compile() + + service = module.get(UsersService) + }) + + afterAll(async () => { + await module.close() + }) + + it('should create and retrieve a user', async () => { + const user = await service.create({ + email: 'test@example.com', + name: 'Test User', + }) + + const found = await service.findOne(user.id) + expect(found.email).toBe('test@example.com') + }) +}) +``` + +### API Tests + +Test HTTP endpoints end-to-end: + +```typescript +// users.e2e.spec.ts +describe('Users API', () => { + let app: INestApplication + + beforeAll(async () => { + const module = await Test.createTestingModule({ + imports: [AppModule], + }).compile() + + app = module.createNestApplication() + await app.init() + }) + + it('POST /users should create a user', async () => { + const response = await request(app.getHttpServer()) + .post('/users') + .send({ email: 'new@example.com', name: 'New User' }) + .expect(201) + + expect(response.body).toHaveProperty('id') + expect(response.body.email).toBe('new@example.com') + }) +}) +``` + +## Frontend Testing + +### E2E Tests + +Use Playwright for end-to-end browser testing: + +```typescript +// tests/e2e/login.spec.ts +import { test, expect } from '@playwright/test' + +test('user can log in', async ({ page }) => { + await page.goto('/login') + await page.fill('[data-testid="email"]', 'user@example.com') + await page.fill('[data-testid="password"]', 'password123') + await page.click('[data-testid="submit"]') + + await expect(page).toHaveURL('/dashboard') + await expect(page.locator('[data-testid="welcome"]')).toContainText('Welcome') +}) +``` + +## Conventions + +### Test File Naming + +- Unit/integration tests: `.spec.ts` (co-located with source) +- E2E tests: `tests/e2e/.spec.ts` + +### Test Naming + +Use descriptive `describe` and `it` blocks that read as sentences: + +```typescript +describe('UsersService', () => { + describe('create', () => { + it('should create a user with valid data', () => { ... }) + it('should throw ConflictException for duplicate email', () => { ... }) + it('should hash the password before storing', () => { ... }) + }) +}) +``` + +### Data Test IDs + +Use `data-testid` attributes for E2E selectors instead of CSS classes or element types: + +```vue + +``` + +## Coverage + +- We do not enforce strict coverage thresholds — coverage is a guide, not a goal +- Focus on testing critical paths: authentication, payments, data mutations +- New features should include tests for the happy path and key edge cases +- CI runs all tests on every PR — failing tests block the merge + +## Tools Summary + +| Tool | Purpose | +|---|---| +| **Jest** | Unit and integration testing (default) | +| **Playwright** | E2E browser testing (preferred) | +| **Cypress** | E2E browser testing (legacy projects) | +| **supertest** | HTTP endpoint testing in NestJS | diff --git a/docs/teams/fullstack/coding_standards/40_error_handling.md b/docs/teams/fullstack/coding_standards/40_error_handling.md index f0f5133d..83001e8b 100644 --- a/docs/teams/fullstack/coding_standards/40_error_handling.md +++ b/docs/teams/fullstack/coding_standards/40_error_handling.md @@ -216,35 +216,9 @@ async createUser(userData: CreateUserDto): Promise { ## Logging -### 1. Winston Configuration +### 1. Pino Configuration -```typescript -// config/winston.config.ts -import { WinstonModule } from 'nest-winston'; -import * as winston from 'winston'; - -export const winstonConfig = WinstonModule.createLogger({ - transports: [ - // Console transport for development - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.colorize(), - winston.format.simple() - ), - }), - - // Google Cloud Logging - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.json() - ), - }), - ], - level: process.env.LOG_LEVEL || 'info', -}); -``` +We use Pino via `nestjs-pino` for structured logging. See [Monitoring & Alerting](../deployment/20_monitoring.md) for the setup. ### 2. Structured Logging @@ -350,39 +324,6 @@ export class LoggingInterceptor implements NestInterceptor { } ``` -### 5. Future: Elasticsearch Integration - -```typescript -// config/elasticsearch-logger.config.ts -import { ElasticsearchTransport } from 'winston-elasticsearch'; - -const elasticsearchTransport = new ElasticsearchTransport({ - level: 'info', - clientOpts: { - node: process.env.ELASTICSEARCH_URL, - auth: { - username: process.env.ELASTICSEARCH_USERNAME, - password: process.env.ELASTICSEARCH_PASSWORD, - }, - }, - indexPrefix: 'logs', - ensureMappingTemplate: true, - mappingTemplate: { - index_patterns: ['logs-*'], - settings: { - number_of_shards: 1, - number_of_replicas: 0, - }, - }, -}); - -// Add to winston config -transports: [ - // ... existing transports - elasticsearchTransport, -] -``` - --- ## Best Practices diff --git a/docs/teams/fullstack/deployment/00_deployment.md b/docs/teams/fullstack/deployment/00_deployment.md index 0028bb2f..d085bf7f 100644 --- a/docs/teams/fullstack/deployment/00_deployment.md +++ b/docs/teams/fullstack/deployment/00_deployment.md @@ -1,2 +1,119 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Deployment Process + +This guide covers our CI/CD approach and deployment workflow for promoting code from development to production. + +## Pipeline Overview + +Every project uses GitHub Actions for CI/CD. The specific workflow configuration varies per project, but the general flow is the same: + +``` +PR opened → Lint + Test + Build → Review → Merge to develop → Deploy to dev + ↓ + Merge to main → Deploy to production +``` + +## CI — Continuous Integration + +CI runs automatically on every pull request. The goal is to catch issues before code is merged. + +**Every CI pipeline should include:** + +1. **Install dependencies** — `npm ci` (or `yarn install --frozen-lockfile`) +2. **Lint** — Run ESLint + Prettier checks +3. **Test** — Run unit and integration tests +4. **Build** — Verify the project compiles successfully + +Some projects also run type checking (`tsc --noEmit`) or security audits (`npm audit`) as part of CI. + +If the project has integration tests that need a database, the workflow should spin up a PostgreSQL (or other) service container for the test run. + +## CD — Continuous Deployment + +Deployment is triggered automatically when code is merged into a target branch. The exact deployment steps depend on the hosting platform (GCP, Digital Ocean, etc.), but the general process is: + +1. **Build a Docker image** from the merged code +2. **Tag the image** with the git commit SHA for traceability +3. **Push the image** to the project's container registry +4. **Deploy** to the target environment using the platform's CLI or API + +Each project defines its own deployment workflow based on its infrastructure. Workflows are stored in `.github/workflows/` and should be reviewed like any other code change. + +## Environment Promotion + +Code flows through environments in a strict order: + +| Branch | Environment | URL pattern | Auto-deploy | +|---|---|---|---| +| `develop` | Development | `dev.project.example.com` | Yes, on merge | +| `staging` | Staging | `staging.project.example.com` | Manual or on merge | +| `main` | Production | `project.example.com` | Yes, on merge | + +### Pre-deployment Checklist + +Before merging to `main` (production): + +- [ ] All CI checks pass +- [ ] PR has been reviewed and approved +- [ ] Changes have been tested on the dev environment +- [ ] Database migrations are backward-compatible (see below) +- [ ] No breaking API changes without versioning + +## Docker Images + +### Tagging + +We tag Docker images with the git commit SHA so every deployed version is traceable back to a specific commit. For production releases, we may also add a semantic version tag (e.g., `v1.2.3`). + +### Container Registry + +The registry depends on the project's hosting platform: + +- **GCP projects**: Google Artifact Registry +- **DO projects**: Digital Ocean Container Registry +- **GitHub**: GitHub Container Registry (ghcr.io) for open-source projects + +## Database Migrations + +Migrations run as part of the deployment process, before the new application version starts serving traffic. + +### Deployment Order + +1. **Run migrations** — apply schema changes +2. **Start new containers** — deploy the updated application +3. **Health check** — verify the new version is responding +4. **Route traffic** — switch traffic to the new version + +### Backward-Compatible Migrations + +To enable zero-downtime deployments, migrations must be backward-compatible with the currently running code: + +**Do:** + +- Add new columns as nullable or with defaults +- Create new tables +- Add new indexes + +**Don't:** + +- Drop columns that the current version still reads +- Rename columns in a single step (use a two-step migration instead) +- Add non-nullable columns without defaults + +## Secrets Management + +Environment variables and secrets are configured per environment: + +- **GCP**: Google Secret Manager +- **Digital Ocean**: App Platform environment variables (encrypted) +- **GitHub Actions**: Repository / environment secrets + +See [Secrets Management](../dev_env/10_secrets.md) for details. + +## Post-deployment + +After every production deployment: + +1. Verify the application is healthy (check monitoring dashboard) +2. Smoke test critical paths (login, core features) +3. Monitor error rates in Sentry for the first 15-30 minutes +4. If issues are detected, follow the [Rollback Procedures](10_rollback.md) diff --git a/docs/teams/fullstack/deployment/10_rollback.md b/docs/teams/fullstack/deployment/10_rollback.md index 0028bb2f..7e684821 100644 --- a/docs/teams/fullstack/deployment/10_rollback.md +++ b/docs/teams/fullstack/deployment/10_rollback.md @@ -1,2 +1,103 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Rollback Procedures + +When a deployment introduces critical issues, we need to revert quickly. This guide covers rollback strategies for different scenarios. + +## Quick Rollback + +The fastest rollback is redeploying the previous known-good revision. Both GCP and Digital Ocean keep a history of deployed revisions, making this straightforward. + +### Via Platform Admin Console (Most Common) + +This is the approach we use most often — no CLI needed. + +=== "GCP Cloud Run" + + 1. Open the [Cloud Run console](https://console.cloud.google.com/run) + 2. Select the affected service + 3. Go to the **Revisions** tab + 4. Find the previous healthy revision + 5. Click **Manage Traffic** and route 100% traffic to the previous revision + +=== "Digital Ocean App Platform" + + 1. Open the [Apps dashboard](https://cloud.digitalocean.com/apps) + 2. Select the affected app + 3. Go to the **Activity** tab + 4. Find the last successful deployment + 5. Click **Rollback to this deployment** + +### Via GitHub Actions + +Alternatively, you can rerun the last successful deployment workflow from the GitHub Actions tab. This rebuilds and redeploys the previous version. + +### Via Git (New Deployment) + +If the platform UI is not available or you need a code-level revert: + +1. `git revert` the problematic commit(s) on the target branch +2. Push — the CI/CD pipeline will deploy the reverted code automatically + +## Database Rollback + +Database rollbacks are more complex and depend on the nature of the migration. + +### Reversible Migrations + +If the migration tool supports down migrations, you can revert the last migration. Always verify what the down migration does before running it. + +### Non-reversible Migrations + +If the migration added data, changed types, or dropped columns: + +1. **Do NOT** run a down migration blindly +2. Assess the impact — can the previous code work with the new schema? +3. If yes, just roll back the application and leave the database as-is +4. If no, create a new forward migration that undoes the change safely +5. For data loss scenarios, restore from backup (see below) + +### Restoring from Backup + +As a last resort, restore the database from a point-in-time backup. Both GCP Cloud SQL and Digital Ocean Managed Databases support this through their admin consoles: + +- **GCP**: Cloud SQL → Instance → Backups → Restore +- **Digital Ocean**: Databases → Select DB → Backups → Restore + +!!! warning "Data Loss" + Restoring a backup will lose all data written after the backup was taken. Only use this as a last resort and communicate with the team before proceeding. + +## Rollback Decision Tree + +``` +Issue detected after deployment + │ + ├── Application error (code bug)? + │ → Roll back to previous revision in platform console + │ + ├── Migration broke the schema? + │ ├── Previous code works with new schema? + │ │ → Roll back application only (leave DB as-is) + │ └── Previous code doesn't work with new schema? + │ → Create corrective migration + redeploy + │ + └── Data corruption? + → Restore from backup + roll back application +``` + +## Incident Response Steps + +When a production issue is detected: + +1. **Acknowledge** — Notify the team in Slack that you're investigating +2. **Assess severity** — Is the app down? Is data being corrupted? Is it a visual bug? +3. **Decide on rollback** — Use the decision tree above +4. **Execute rollback** — Roll back to previous revision and/or fix the database +5. **Verify** — Confirm the rollback resolved the issue +6. **Communicate** — Update the team and affected stakeholders +7. **Post-mortem** — Document what happened, why, and how to prevent it + +## Prevention + +- Always test migrations against a copy of production data before deploying +- Use backward-compatible migrations (see [Deployment Process](00_deployment.md)) +- Deploy during low-traffic periods for high-risk changes +- Keep deployments small and frequent — smaller changes are easier to roll back diff --git a/docs/teams/fullstack/deployment/20_monitoring.md b/docs/teams/fullstack/deployment/20_monitoring.md index 0028bb2f..a11577ed 100644 --- a/docs/teams/fullstack/deployment/20_monitoring.md +++ b/docs/teams/fullstack/deployment/20_monitoring.md @@ -1,2 +1,145 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Monitoring & Alerting + +This guide covers the baseline observability practices we use across projects. Different projects have different monitoring needs — Sentry and structured logging are our standard everywhere, while more advanced tooling (APM, custom dashboards, detailed alerting) is set up per project based on its requirements and is not documented here. + +## Error Tracking + +### Sentry + +Sentry is our primary error tracking tool for both backend and frontend applications. It's present in almost every project. + +#### Backend Setup (NestJS) + +```typescript +// main.ts +import * as Sentry from '@sentry/node' + +Sentry.init({ + dsn: process.env.SENTRY_DSN, + environment: process.env.NODE_ENV, + tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.2 : 1.0, +}) +``` + +```typescript +// shared/filters/sentry-exception.filter.ts +@Catch() +export class SentryExceptionFilter implements ExceptionFilter { + catch(exception: unknown, host: ArgumentsHost) { + Sentry.captureException(exception) + // ... pass to default exception handler + } +} +``` + +#### Frontend Setup (Vue / Nuxt) + +```typescript +// plugins/sentry.client.ts +import * as Sentry from '@sentry/vue' + +export default defineNuxtPlugin((nuxtApp) => { + Sentry.init({ + app: nuxtApp.vueApp, + dsn: useRuntimeConfig().public.sentryDsn, + environment: useRuntimeConfig().public.environment, + tracesSampleRate: 0.2, + }) +}) +``` + +#### Best Practices + +- Set meaningful `environment` and `release` tags +- Add user context when available (`Sentry.setUser({ id, email })`) +- Use breadcrumbs to trace the sequence of events leading to an error +- Filter out expected errors (4xx responses, validation errors) to reduce noise + +## Logging + +We use **Pino** for structured JSON logging. Pino is fast, low-overhead, and works well with NestJS. + +### Setup + +```typescript +// main.ts +import { LoggerModule } from 'nestjs-pino' + +@Module({ + imports: [ + LoggerModule.forRoot({ + pinoHttp: { + level: process.env.LOG_LEVEL || 'info', + transport: process.env.NODE_ENV !== 'production' + ? { target: 'pino-pretty' } + : undefined, + }, + }), + ], +}) +export class AppModule {} +``` + +### Key Guidelines + +- Use structured JSON logging in production (Pino does this by default) +- Include correlation/request IDs for tracing requests across services +- Log at appropriate levels: `error` for failures, `warn` for degraded behavior, `info` for significant events, `debug` for development +- Never log sensitive data (passwords, tokens, PII) +- Use `pino-pretty` in development for readable output + +### Log Aggregation + +- **GCP projects**: Logs are automatically collected by Google Cloud Logging when output as JSON to stdout +- **DO projects**: Use Digital Ocean's built-in log viewer or forward logs to a centralized service + +See [Error Handling & Logging](../coding_standards/40_error_handling.md) for more patterns on structured logging and error context. + +## Health Checks + +Every application exposes a health check endpoint: + +```typescript +// health/health.controller.ts +@Controller('health') +export class HealthController { + constructor( + private health: HealthCheckService, + private db: TypeOrmHealthIndicator, + ) {} + + @Get() + check() { + return this.health.check([ + () => this.db.pingCheck('database'), + ]) + } +} +``` + +Health checks are used by: + +- **Load balancers** to route traffic to healthy instances +- **Container orchestrators** to restart unhealthy containers +- **Uptime monitors** to detect outages + +## Alerting + +### Alert Channels + +- **Slack** — Primary channel for all alerts +- **Email** — Backup for critical alerts + +### What to Alert On + +- Application errors spiking above baseline (Sentry alerts) +- Health check failures +- High response time sustained over several minutes +- Resource usage thresholds (CPU, memory) + +### Avoiding Alert Fatigue + +- Only alert on actionable conditions — if no one needs to act, it's a log, not an alert +- Group related errors in Sentry (deduplication) +- Set reasonable thresholds — occasional 500 errors happen, only alert on sustained issues +- Review and tune alert rules periodically diff --git a/docs/teams/fullstack/deployment/30_ops.md b/docs/teams/fullstack/deployment/30_ops.md new file mode 100644 index 00000000..b12ae552 --- /dev/null +++ b/docs/teams/fullstack/deployment/30_ops.md @@ -0,0 +1,105 @@ +# Operations & Access Management + +This guide covers operational practices for managing project infrastructure, accounts, and access controls. + +## Current State & Goals + +!!! warning "Current State" + + Access management and operational setup is inconsistent across projects. Many projects use personal accounts for services, lack standardized email configurations, and have no formal access audit process. This section defines where we want to be. + +## Service Accounts + +**Never use personal accounts for project infrastructure.** All external services, cloud resources, and third-party integrations should use dedicated service accounts. + +### Naming Convention Example + +``` +Service email: ops+@futured.app +Cloud accounts: -service@.iam.gserviceaccount.com +GitHub bot: futured-bot (org-level) +``` + +### What Needs a Service Account + +| Service | Account type | Owner | +|---|---|---| +| Cloud provider (GCP/DO) | Service account with scoped IAM roles | Project owner | +| Container registry | Deploy token or service account | CI/CD pipeline | +| Sentry | Organization-level, project-scoped | Project owner | +| Email provider (Resend, etc.) | API key tied to ops email | Project owner | +| Payment provider (Stripe, etc.) | Organization account, not personal | Project owner + delivery | +| DNS / Domain registrar | Organization account | Ops specialist | + +### Rules + +- Service accounts use the minimum permissions needed (principle of least privilege) +- API keys and tokens are stored in the cloud provider's secret manager, never in code or personal password managers +- When a team member leaves, their personal access is revoked — service accounts remain unaffected + +## Email Configuration Example + +Every project should have standardized email addresses: + +``` +ops+@futured.app — Infrastructure alerts, monitoring +noreply+@futured.app — Transactional emails (password resets, notifications) +support+@futured.app — User-facing support (if applicable) +``` + +## Access Audit + +Quarterly access audit checklist per project: + +- [ ] List all service accounts and their permissions — remove unused ones +- [ ] Verify no personal accounts are used for infrastructure +- [ ] Rotate API keys and tokens that haven't been rotated in 90+ days +- [ ] Review cloud IAM roles — remove overly broad permissions +- [ ] Ensure all team members have appropriate access (not too much, not too little) +- [ ] Verify GitHub repository access matches current team composition + +## Container Registry & OCI + +### Registry Setup + +- **GCP**: Google Artifact Registry — one registry per project or shared within an environment +- **DO**: Digital Ocean Container Registry +- **GitHub**: `ghcr.io` for open-source projects + +### Best Practices + +- Tag images with git commit SHA for traceability (see [Deployment Process](00_deployment.md)) +- Set up image retention policies — auto-delete images older than 90 days (except tagged releases) +- Scan images for vulnerabilities in CI (e.g. `trivy`, `grype`) +- Use multi-stage builds to minimize image size and attack surface +- Pin base image versions (e.g. `node:20.11-alpine`, not `node:latest`) + +## Cloud Resource Organization + +### GCP + +``` +Organization: futured.app + └── Project: -- + ├── Cloud Run (compute) + ├── Cloud SQL (database) + ├── Secret Manager (secrets) + └── Cloud Storage (files) +``` + +### Digital Ocean + +``` +Team: Futured + └── Project: - + ├── App Platform (compute) + ├── Managed Database + └── Spaces (files) +``` + +### Rules + +- Separate cloud projects/environments for dev and production +- Use consistent naming across all resources +- Tag resources with project name and environment for cost tracking +- Set up billing alerts to catch unexpected cost spikes \ No newline at end of file diff --git a/docs/teams/fullstack/dev_env/00_local_setup.md b/docs/teams/fullstack/dev_env/00_local_setup.md index 27e89622..cbe70802 100644 --- a/docs/teams/fullstack/dev_env/00_local_setup.md +++ b/docs/teams/fullstack/dev_env/00_local_setup.md @@ -18,7 +18,7 @@ We recommend using Node Version Manager (nvm) for Node.js: ```bash # Install nvm (if not already installed) -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash # Restart your terminal or run: source ~/.bashrc @@ -43,8 +43,8 @@ cd git fetch origin # Checkout the development branch -git checkout dev -git pull origin dev +git checkout develop +git pull origin develop ``` @@ -60,6 +60,18 @@ nano docker-compose.yml **Important:** Never commit `docker-compose.yml` with actual secrets to version control. +### 3. Configure Local Domains (if required) + +Some projects use custom local domains instead of `localhost`. Check the project README — if it requires a local domain, add it to your hosts file: + +```bash +# Edit hosts file +sudo nano /etc/hosts + +# Add the required entry (example) +127.0.0.1 my-project.local +``` + ### 4. Request Environment Variables If you don't have the required environment variables: @@ -87,25 +99,25 @@ If you don't have the required environment variables: ```bash # Build all services (first time or after changes) -docker-compose build +docker compose build # Start all services in detached mode -docker-compose up -d +docker compose up -d # Check service status -docker-compose ps +docker compose ps ``` ### 2. Verify Services Are Running ```bash # Check all containers are healthy -docker-compose ps +docker compose ps # View logs for any issues -docker-compose logs api -docker-compose logs postgres -docker-compose logs cache +docker compose logs api +docker compose logs postgres +docker compose logs cache ``` ### 3. Access Your Application @@ -125,11 +137,11 @@ The correct migration command is always specified in the project's `package.json ```bash # Run migrations inside the API container -docker-compose exec api npm run migrate +docker compose exec api npm run migrate # Or if using a specific migration tool -docker-compose exec api npx prisma migrate dev -docker-compose exec api npx typeorm migration:run +docker compose exec api npx prisma migrate dev +docker compose exec api npx typeorm migration:run ``` **Always check the project's documentation for the correct command.** @@ -140,10 +152,10 @@ The correct seed command is always specified in the project's `package.json` and ```bash # Run seed scripts -docker-compose exec api npm run seed +docker compose exec api npm run seed # Or manually seed if needed -docker-compose exec api npm run seed:dev +docker compose exec api npm run seed:dev ``` **Always check the project's documentation for the correct command.** @@ -157,6 +169,7 @@ We recommend using GUI tools for database access: - **pgAdmin** - PostgreSQL-specific administration tool Connect using these credentials (from your `docker-compose.yml`): + - **Host**: localhost - **Port**: 5432 - **Database**: (check your docker-compose.yml) @@ -184,22 +197,37 @@ git checkout -b feature/your-feature-name ```bash # Run tests -docker-compose exec api npm test +docker compose exec api npm test # Run linting -docker-compose exec api npm run lint +docker compose exec api npm run lint # Run type checking -docker-compose exec api npm run type-check +docker compose exec api npm run type-check ``` ### 3. Hot Reloading The development environment includes hot reloading: + - API changes trigger automatic restarts - Frontend changes are reflected immediately - Database changes require manual migration runs +### 4. Rebuilding After Dependency Changes + +When `package.json` changes (new packages added, versions updated), you need to rebuild the Docker image for that service: + +```bash +# Rebuild the affected service +docker compose build api + +# Restart with the new image +docker compose up -d +``` + +Source code changes don't require a rebuild — they're picked up automatically via volume mounts. Only dependency or Dockerfile changes need a rebuild. + --- ## Troubleshooting @@ -223,7 +251,7 @@ sudo systemctl stop conflicting-service docker system prune -f # Rebuild without cache -docker-compose build --no-cache +docker compose build --no-cache # Restart Docker Desktop (if on macOS/Windows) ``` @@ -231,22 +259,22 @@ docker-compose build --no-cache #### 3. Database Connection Issues ```bash # Check if database is running -docker-compose ps postgres +docker compose ps postgres # View database logs -docker-compose logs postgres +docker compose logs postgres # Reset database container -docker-compose restart postgres +docker compose restart postgres ``` #### 4. Environment Variable Problems ```bash # Verify environment variables are loaded -docker-compose exec api env | grep DATABASE_URL +docker compose exec api env | grep DATABASE_URL # Check docker-compose.yml syntax -docker-compose config +docker compose config ``` ### Performance Issues @@ -254,7 +282,7 @@ docker-compose config #### 1. Slow Builds ```bash # Use build cache -docker-compose build --parallel +docker compose build --parallel # Optimize Dockerfile with multi-stage builds # Use .dockerignore to exclude unnecessary files @@ -275,6 +303,7 @@ volumes: ### Check README.md Always check the project's README.md for: + - Project-specific setup instructions - Additional dependencies - Special configuration requirements @@ -283,6 +312,7 @@ Always check the project's README.md for: ### Environment Differences Different projects may require: + - Different Node.js versions - Additional services (Redis, MongoDB, etc.) - Specific environment variables @@ -293,7 +323,7 @@ Different projects may require: ## Best Practices ### 1. Git Workflow -- Always work from the latest `dev` branch +- Always work from the latest `develop` branch - Pull latest changes regularly ### 2. Docker Usage @@ -307,8 +337,8 @@ Different projects may require: - Use database migrations for schema changes ### 4. Troubleshooting -- Check logs first: `docker-compose logs ` +- Check logs first: `docker compose logs ` - Verify environment variables are set correctly -- Ensure all services are running: `docker-compose ps` +- Ensure all services are running: `docker compose ps` - Check for port conflicts -- Restart services when in doubt: `docker-compose restart` +- Restart services when in doubt: `docker compose restart` diff --git a/docs/teams/fullstack/dev_env/10_secrets.md b/docs/teams/fullstack/dev_env/10_secrets.md index bdebcf4a..45fb3624 100644 --- a/docs/teams/fullstack/dev_env/10_secrets.md +++ b/docs/teams/fullstack/dev_env/10_secrets.md @@ -19,8 +19,6 @@ We use Docker Compose with environment variables for local development. The conf #### `docker-compose.yml` (Template) ```yaml -version: '3.7' - services: api: build: @@ -50,6 +48,7 @@ services: ### Git Configuration **Never commit these files:** + - `docker-compose.yml` (with actual secrets) - `.env` - `.env.local` @@ -57,6 +56,7 @@ services: - Any file containing actual secret values **Always commit these files:** + - `docker-compose.dist.yml` - Template showing required variables - `.env.example` - Template showing required variables - `.env.dist` - Distribution template (same as .env.example) @@ -95,7 +95,7 @@ cp docker-compose.dist.yml docker-compose.yml nano docker-compose.yml # Start the application with Docker Compose -docker-compose up -d +docker compose up -d ``` ### 2. README Documentation @@ -114,7 +114,7 @@ Include a section in your README.md: | Variable | Description | Example | |----------|-------------|---------| | `DATABASE_URL` | PostgreSQL connection string | `postgresql://user:pass@postgres/db` | -| `_API_KEY` | API key | `your-api-key` | +| `API_KEY` | API key | `your-api-key` | | `OAUTH_KEY` | OAuth authentication key | `your-oauth-key` | | `CLIENT_ID` | Client ID for authentication | `your-client-id` | @@ -144,7 +144,7 @@ gcloud secrets add-iam-policy-binding DATABASE_URL \ --role="roles/secretmanager.secretAccessor" ``` -**Note:** You can also create and manage secrets through the Google Cloud Console UI at https://console.cloud.google.com/security/secret-manager +**Note:** You can also create and manage secrets through the Google Cloud Console UI at [https://console.cloud.google.com/security/secret-manager](https://console.cloud.google.com/security/secret-manager) #### Cloud Run / App Engine ```yaml diff --git a/docs/teams/fullstack/dev_env/20_ai_tools.md b/docs/teams/fullstack/dev_env/20_ai_tools.md new file mode 100644 index 00000000..c4ae42a3 --- /dev/null +++ b/docs/teams/fullstack/dev_env/20_ai_tools.md @@ -0,0 +1,123 @@ +# AI-Assisted Development + +AI tools have become an integral part of modern software development. This guide covers how we use them effectively and safely. + +## Tools We Use + +### Code Assistants + +- **GitHub Copilot** — Inline code suggestions in the IDE. Useful for boilerplate, repetitive patterns, and exploring unfamiliar APIs. +- **Claude Code** — CLI-based AI assistant for larger tasks: refactoring, writing tests, exploring codebases, generating code across multiple files. +- **Cursor** — VS Code fork with built-in AI features, including multi-file editing and codebase-aware completions. + +### Code Review + +- **CodeRabbit** — Automated PR analysis that flags potential issues, suggests improvements, and provides summaries. +- **GitHub Copilot in PRs** — Summarizes changes and suggests improvements directly in pull requests. + +### Documentation & Communication + +- AI tools can help draft documentation, README files, and commit messages — but always review the output for accuracy. + +## Guidelines for Effective Use + +### When AI Helps Most + +- **Boilerplate code** — CRUD endpoints, DTOs, entity definitions, test scaffolding +- **Exploring unfamiliar APIs** — "How do I use X in NestJS?" is faster to ask an AI than to browse docs +- **Writing tests** — AI is good at generating test cases, especially edge cases you might miss +- **Refactoring** — Renaming, restructuring, converting between patterns +- **Code review** — Catching common issues, suggesting improvements + +### When to Be Careful + +- **Business logic** — AI doesn't know your domain. Verify that generated logic actually matches the requirements. +- **Security-sensitive code** — Authentication, authorization, encryption. Always review carefully. +- **Database migrations** — AI-generated migrations can be subtly wrong. Test against real data. +- **Configuration** — CI/CD pipelines, Terraform, Docker configs. A small mistake can break production. + +### General Principles + +1. **AI suggests, you decide** — Treat AI output as a first draft, not final code +2. **Understand what you commit** — If you can't explain the code, don't commit it +3. **Review as if a junior wrote it** — AI produces plausible-looking code that can have subtle bugs +4. **Test AI-generated code** — It compiles doesn't mean it works correctly +5. **Don't disable your brain** — AI accelerates your work, it doesn't replace your judgment + +## Security Rules + +!!! warning "Critical Security Rules" + + - **Never paste secrets** (API keys, tokens, passwords, private keys) into AI prompts + - **Never paste customer data** or PII into AI tools + - **Be cautious with proprietary code** — check your AI tool's data retention policy + - **Don't trust AI for security decisions** — it may suggest insecure patterns that look correct + +### What's Safe to Share with AI + +- Open-source code and public documentation +- Generic code patterns and architecture questions +- Error messages and stack traces (after removing secrets) +- Code from your own repositories (if using tools with data privacy guarantees like Copilot, Claude Code) + +### What's NOT Safe to Share + +- Environment variables, API keys, tokens +- Customer data or production database contents (PII — personally identifiable information) +- Internal infrastructure details (IP addresses, server configurations) +- Credentials or authentication tokens + +## AI in Code Review + +AI code review tools (CodeRabbit, Copilot) are part of our PR workflow, but they supplement — not replace — human review. + +**What AI review catches well:** + +- Common anti-patterns and code smells +- Missing error handling +- Inconsistent naming or formatting +- Potential performance issues +- Security basics (SQL injection, XSS) + +**What requires human review:** + +- Business logic correctness +- Architectural fit (does this belong here?) +- Context-specific decisions +- Edge cases that depend on domain knowledge + +## AI Workflows We're Exploring + +Beyond code assistance, we're actively exploring AI in other parts of our workflow: + +### Test Generation + +- **Claude Code / Copilot** — Generate test scaffolding from existing code. Particularly useful for generating integration test boilerplate and edge case coverage. +- **Goal**: Every new feature PR includes AI-assisted test suggestions as a starting point for the developer to review and refine. + +### Figma to Code + +- Exploring tools that translate Figma designs into Vue/React components +- Current state: experimental, not part of any production workflow yet +- Key challenge: generated code needs significant cleanup to match our component structure and coding standards +- **Goal**: Reduce the time from design handoff to initial component implementation + +### AI-Assisted UI Testing + +- Exploring visual regression testing where AI compares screenshots against Figma designs before merge +- Could catch visual regressions that traditional tests miss (layout shifts, styling issues, responsive breakpoints) +- **Goal**: Automated visual QA check as part of the PR pipeline + +### Project Management + +- Jira automation: AI-assisted task breakdown from feature descriptions +- Sprint planning: Using AI to estimate complexity based on codebase analysis +- **Goal**: Reduce overhead of task management, not replace human judgment on priorities + +## Keeping Up + +The AI tooling landscape evolves rapidly. We encourage team members to: + +- Experiment with new tools and share findings +- Discuss useful AI workflows in team meetings +- Update this guide as practices evolve diff --git a/docs/teams/fullstack/development/00_git_flow.md b/docs/teams/fullstack/development/00_git_flow.md index e1ac3302..516b1062 100644 --- a/docs/teams/fullstack/development/00_git_flow.md +++ b/docs/teams/fullstack/development/00_git_flow.md @@ -58,10 +58,34 @@ We use a structured Git branching model to ensure smooth collaboration and maint - **Dangerfile** We use a Dangerfile to automatically check commit and pull request parameters, ensuring adherence to our standards. -### Release Tags - -- **Version Tags** - Optionally, we tag commits with release version numbers (e.g., `v1.2.0`) to mark stable points in our codebase. +### Release Tags & Changelog + +- **Version Tags** + Every production release **must** be tagged with a semantic version number (e.g., `v1.2.0`). Tags are created on the `main` branch after a successful production deployment. + +- **Tagging Convention** + We follow [Semantic Versioning](https://semver.org/): `MAJOR.MINOR.PATCH` + - `MAJOR` — Breaking changes + - `MINOR` — New features, backward-compatible + - `PATCH` — Bug fixes + +- **Changelog** + Every project maintains a `CHANGELOG.md` in the repository root. Changes are documented per release using the [Keep a Changelog](https://keepachangelog.com/) format: + + ```markdown + ## [1.2.0] - 2026-03-06 + ### Added + - User profile editing endpoint + ### Fixed + - Login timeout on slow connections + ### Changed + - Increased pagination default from 10 to 20 + ``` + + Changelog entries should be written as part of the PR process — each PR that adds user-facing or API-impacting changes updates the `[Unreleased]` section. On release, `[Unreleased]` is renamed to the version number. + +- **Conventional Commits (Encouraged)** + Using conventional commit messages (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`) makes changelog generation easier and can be automated with tools like `standard-version` or `release-please`. ### Environments diff --git a/docs/teams/fullstack/development/10_pull_request_guidelines.md b/docs/teams/fullstack/development/10_pull_request_guidelines.md index fbbd65a9..58c5d8da 100644 --- a/docs/teams/fullstack/development/10_pull_request_guidelines.md +++ b/docs/teams/fullstack/development/10_pull_request_guidelines.md @@ -9,8 +9,8 @@ We use GitHub for code collaboration and follow best practices to ensure our pul - **Include Jira Ticket Numbers** Reference the relevant Jira ticket number in the PR title and description to link code changes to tracked work. When it is properly linked, the PR will automatically update the ticket status in Jira. -- **Review Before Submitting** - Test and review your own changes before opening a PR. This helps catch errors early and improves the quality of the review process. +- **Self-Review on GitHub** + Open your PR and review the diff on GitHub before assigning reviewers. Reading changes in the GitHub UI often catches things you miss in your local editor. Mark the PR as draft while you're still reviewing or if CI is running. - **English, Czech and Slovak Only** All PR titles, descriptions, and comments must be written in these languages to ensure clarity for all collaborators. @@ -30,7 +30,7 @@ We use GitHub for code collaboration and follow best practices to ensure our pul Assign your pull request to at least one teammate who is familiar with the relevant codebase or feature area. If unsure, consult your team lead or refer to the code ownership guidelines. - **When to Assign** - Assign reviewers immediately after opening the pull request. This ensures timely feedback and helps keep the development process moving smoothly. + Assign reviewers once CI checks pass and the PR is ready for review. There's no point in requesting a review while tests are still failing — you may end up rewriting the approach. Use draft PRs for work-in-progress, and convert to "Ready for Review" + assign reviewers when CI is green. - **Sync Regularly** Regularly update your branch with the latest changes from the base branch (`develop` or `main`) to minimize merge conflicts and ensure your code is tested against the most recent version. diff --git a/docs/teams/fullstack/development/30_project_setup.md b/docs/teams/fullstack/development/30_project_setup.md index ab54936a..24e784c4 100644 --- a/docs/teams/fullstack/development/30_project_setup.md +++ b/docs/teams/fullstack/development/30_project_setup.md @@ -20,7 +20,7 @@ This guide walks you through setting up a new project in the Futured Github orga ### Branch Protection Rules -Set up branch protection for the `main` and `dev` branches: +Set up branch protection for the `main` and `develop` branches: #### Main Branch Protection ``` @@ -34,9 +34,9 @@ Require branches to be up to date before merging: ✓ Restrict pushes that create files larger than 100 MB: ✓ ``` -#### Dev Branch Protection +#### Develop Branch Protection ``` -Branch name pattern: dev +Branch name pattern: develop Require a pull request before merging: ✓ Require approvals: 1 Dismiss stale PR approvals when new commits are pushed: ✓ @@ -55,6 +55,9 @@ Our internal template repository contains pre-configured templates for common pr **Note:** These templates are currently internal to the Futured organization and not publicly available. We plan to open-source these templates in the future to share our best practices with the broader developer community. +!!! info "AI-Assisted Project Scaffolding" + We are preparing Claude-ready scripts and prompts that will be able to generate the correct project template based on your requirements (API type, database, frontend framework, etc.). Stay tuned for updates. + ### Available Templates 1. REST or GraphQL API inside NestJs project @@ -83,8 +86,6 @@ Our internal template repository contains pre-configured templates for common pr #### Update Docker Configuration ```yaml # docker-compose.dist.yml -version: '3.7' - services: postgres: environment: @@ -173,7 +174,7 @@ cp docker-compose.dist.yml docker-compose.yml nano docker-compose.yml # Start the application -docker-compose up -d +docker compose up -d ``` ## 4. Set Up CI/CD Pipeline diff --git a/docs/teams/fullstack/development/40_project_ownership.md b/docs/teams/fullstack/development/40_project_ownership.md new file mode 100644 index 00000000..e6f7baac --- /dev/null +++ b/docs/teams/fullstack/development/40_project_ownership.md @@ -0,0 +1,86 @@ +# Technical Ownership & Responsibilities + +This guide defines how we assign and manage technical ownership of projects within the fullstack team — who is responsible for the codebase, infrastructure, and technical health of each project. + +## The Problem We're Solving + +Without clear technical ownership, projects drift into "no one's responsibility" territory — dependencies go stale, CI breaks silently, infrastructure config rots, and knowledge concentrates in a single person. This section exists to prevent that. + +## Tech Owner + +Every project has a designated **tech owner** — a fullstack developer who is the go-to person for all technical decisions and the health of the codebase. + +**Responsibilities:** + +- Keeping dependencies up to date (security patches, major upgrades) +- Ensuring CI/CD pipelines are functional +- Reviewing and maintaining infrastructure configuration +- Onboarding new team members to the project codebase +- Maintaining the project README and technical documentation +- Making architecture decisions (or escalating them to the team) + +**Tech ownership is assigned at project kickoff and documented in the project README.** + +### Backup + +Every project must have at least one **backup person** who: + +- Has a working local development environment +- Understands the architecture and key business logic +- Can deploy to production independently +- Is available when the tech owner is unavailable + +This directly addresses the "bus factor" — no project should depend on a single person. + +## No One-Person Shows + +!!! warning "Hard Rule" + + No project should have only one person who can work on it. If you are the only person who understands a project, it is your responsibility to onboard someone else. + +**How to prevent one-person shows:** + +- Pair programming sessions during complex feature development +- Documented architecture decisions (ADRs) in the repository +- Regular knowledge-sharing during cross-project syncs +- Rotate who handles hotfixes and deployments + +## Cross-Project Syncs + +The team holds regular syncs to share knowledge across projects: + +- **What**: Short updates on architecture decisions, interesting problems, new patterns +- **Why**: Prevent knowledge silos, share reusable solutions, align on team-wide practices +- **Format**: Each tech owner gives a 5-minute update on anything noteworthy + +## Gray Area Responsibilities + +The fullstack team sometimes touches things outside its core scope — DevOps, infrastructure, email setup, third-party service configuration. These need clear boundaries: + +- **If it's a one-time setup** (e.g. DNS, email config) — document it and hand off to the appropriate team or ops specialist +- **If it's ongoing maintenance** (e.g. infrastructure monitoring) — assign explicit ownership, don't let it fall between teams +- **If you're unsure who owns it** — raise it in the cross-project sync and assign it + +The goal is not to own everything — it's to make sure nothing is unowned. + +## Project Handover Checklist + +When a project changes tech ownership or a team member leaves: + +- [ ] README is up to date with setup instructions, architecture overview, and key contacts +- [ ] All credentials and access are transferred (no personal accounts) +- [ ] CI/CD pipelines are documented and functional +- [ ] The backup person has deployed to production at least once +- [ ] Open issues and technical debt are documented +- [ ] Knowledge transfer session completed (recorded if possible) + +## Project Health Audits + +Periodically (quarterly recommended), the tech owner reviews their project for: + +- [ ] Dependencies are up to date (no critical security vulnerabilities) +- [ ] CI/CD is green and runs in a reasonable time +- [ ] Access controls use service accounts, not personal accounts +- [ ] Monitoring and alerting are functional +- [ ] Documentation reflects the current state of the project +- [ ] At least two people can work on and deploy the project \ No newline at end of file diff --git a/docs/teams/fullstack/docs/00_code_docs.md b/docs/teams/fullstack/docs/00_code_docs.md index 0028bb2f..74a64dcf 100644 --- a/docs/teams/fullstack/docs/00_code_docs.md +++ b/docs/teams/fullstack/docs/00_code_docs.md @@ -1,2 +1,139 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Code Documentation Standards + +Good documentation helps new team members onboard faster and makes codebases easier to maintain. This guide covers when and how to document code. + +## Philosophy + +- **Code should be self-documenting** — use clear naming, small functions, and obvious structure +- **Document the why, not the what** — if you need to explain *what* the code does, consider rewriting it to be clearer +- **Don't over-document** — unnecessary comments become noise and go stale + +## When to Document + +**Always document:** + +- REST API endpoints — via Swagger/OpenAPI decorators (see [API Documentation](10_api_docs.md)) +- GraphQL types and fields — via `description` annotations +- Complex business logic that isn't obvious from the code +- Non-obvious decisions ("we do X instead of Y because...") +- Workarounds and known limitations +- Configuration options + +**Skip documentation for:** + +- Self-evident code (`getUserById` doesn't need a comment) +- Internal utility functions with clear naming +- Code that changes frequently (comments go stale) + +## Public API Documentation + +For REST endpoints, we use **Swagger/OpenAPI decorators** — not JSDoc. See [API Documentation](10_api_docs.md) for details on `@ApiOperation`, `@ApiResponse`, and `@ApiProperty`. + +For GraphQL, we use the built-in **`description` option** on `@ObjectType`, `@Field`, `@Query`, and `@Mutation` decorators. The schema itself serves as documentation. + +## Service Method Comments + +For internal service methods with non-obvious behavior, use JSDoc comments: + +```typescript +/** + * Creates a new user account and sends a welcome email. + * + * @throws ConflictException if a user with this email already exists + * @throws BadRequestException if the email domain is blacklisted + */ +async createUser(dto: CreateUserDto): Promise { + // ... +} +``` + +**Guidelines:** + +- Use `@throws` to document exceptions a caller should handle +- Use `@returns` when the return value isn't obvious from the type signature +- Use `@param` only when parameter names alone aren't sufficient +- Skip JSDoc for simple CRUD methods — the types and Swagger decorators say enough + +## Inline Comments + +Use inline comments sparingly, for non-obvious logic: + +```typescript +// PostgreSQL error code 23505 = unique constraint violation +if (error.code === '23505') { + throw new ConflictException('Email already exists') +} +``` + +```typescript +// We fetch N+1 items to determine if there's a next page +// without running a separate COUNT query +const items = await repo.find({ take: limit + 1 }) +``` + +**Avoid:** + +```typescript +// BAD: states the obvious +// Get user by ID +const user = await this.usersService.findById(id) + +// BAD: restates the type +// The user's email address (string) +email: string +``` + +## Project README + +Every project repository must have a `README.md` with: + +1. **Project description** — What it does, who it's for +2. **Quick start** — Steps to get the project running locally +3. **Environment variables** — Table of required variables with descriptions +4. **Available scripts** — What `npm run dev`, `npm run test`, etc. do +5. **Architecture overview** — Brief description of the project structure (for larger projects) +6. **Deployment** — How and where the project is deployed + +### Template + +```markdown +# Project Name + +Brief description of the project. + +## Quick Start + +1. Clone the repository +2. `cp docker-compose.dist.yml docker-compose.yml` +3. Fill in environment variables +4. `docker compose up -d` +5. `docker compose exec api npm run migrate` + +## Environment Variables + +| Variable | Description | Required | +|---|---|---| +| `DATABASE_URL` | PostgreSQL connection string | Yes | +| `JWT_SECRET` | Secret for signing JWTs | Yes | + +## Scripts + +| Script | Description | +|---|---| +| `npm run dev` | Start development server | +| `npm run build` | Build for production | +| `npm run test` | Run tests | +| `npm run lint` | Lint and format check | + +## Architecture + +Brief overview of the project structure and key modules. + +## Deployment + +Deployed via GitHub Actions to [platform]. See `.github/workflows/` for details. +``` + +## Changelog + +For projects with external consumers (APIs used by other teams or clients), maintain a `CHANGELOG.md` following the [Keep a Changelog](https://keepachangelog.com/) format. For internal projects, git history and PR descriptions are sufficient. diff --git a/docs/teams/fullstack/docs/10_api_docs.md b/docs/teams/fullstack/docs/10_api_docs.md index 0028bb2f..2841be31 100644 --- a/docs/teams/fullstack/docs/10_api_docs.md +++ b/docs/teams/fullstack/docs/10_api_docs.md @@ -1,2 +1,162 @@ -!!! warning "Work in progress" - \ No newline at end of file +# API Documentation + +All APIs must be documented in a way that allows consumers (frontend developers, external clients, other teams) to understand and use them without reading the source code. + +## REST APIs — OpenAPI / Swagger + +NestJS has built-in support for generating OpenAPI (Swagger) documentation from decorators. + +### Setup + +```typescript +// main.ts +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger' + +const config = new DocumentBuilder() + .setTitle('MyApp API') + .setDescription('API documentation for MyApp') + .setVersion('1.0') + .addBearerAuth() + .build() + +const document = SwaggerModule.createDocument(app, config) +SwaggerModule.setup('api/docs', app, document) +``` + +The Swagger UI is available at `/api/docs` in development and staging environments. + +!!! warning "Production Access" + Disable or restrict access to Swagger UI in production. Use a guard or environment check to prevent public access to API documentation. + +### Decorating Endpoints + +```typescript +@ApiTags('Users') +@Controller('users') +export class UsersController { + + @ApiOperation({ summary: 'Create a new user' }) + @ApiResponse({ status: 201, description: 'User created successfully', type: UserResponseDto }) + @ApiResponse({ status: 409, description: 'User with this email already exists' }) + @Post() + create(@Body() dto: CreateUserDto): Promise { + return this.usersService.create(dto) + } + + @ApiOperation({ summary: 'Get a user by ID' }) + @ApiParam({ name: 'id', description: 'User UUID' }) + @ApiResponse({ status: 200, type: UserResponseDto }) + @ApiResponse({ status: 404, description: 'User not found' }) + @Get(':id') + findOne(@Param('id', ParseUUIDPipe) id: string): Promise { + return this.usersService.findOne(id) + } +} +``` + +### DTO Documentation + +Use `@ApiProperty` decorators on DTOs so Swagger can generate accurate schemas: + +```typescript +export class CreateUserDto { + @ApiProperty({ example: 'john@example.com', description: 'User email address' }) + @IsEmail() + email: string + + @ApiProperty({ example: 'John Doe', minLength: 2, maxLength: 100 }) + @IsString() + @MinLength(2) + name: string + + @ApiProperty({ enum: UserRole, example: UserRole.EDITOR }) + @IsEnum(UserRole) + role: UserRole +} +``` + +### Best Practices + +- Document all public endpoints with `@ApiOperation` and `@ApiResponse` +- Include example values in `@ApiProperty` — they populate the "Try it out" feature +- Group related endpoints with `@ApiTags` +- Use separate response DTOs (don't expose entity internals like passwords or internal IDs) +- Keep Swagger descriptions concise — they supplement the endpoint names, not replace them + +## GraphQL APIs + +GraphQL is self-documenting by design — the schema serves as the API contract. + +### Schema Documentation + +Add descriptions to types and fields using the `description` option: + +```typescript +@ObjectType({ description: 'A registered user of the application' }) +export class User { + @Field(() => ID) + id: string + + @Field({ description: 'The user display name' }) + name: string + + @Field(() => UserRole, { description: 'The user permission level' }) + role: UserRole +} +``` + +### GraphQL Playground + +GraphQL Playground (or Apollo Sandbox) is available at the GraphQL endpoint in development. It provides: + +- Interactive query builder +- Auto-complete based on the schema +- Documentation explorer showing all types, queries, and mutations + +```typescript +// app.module.ts +GraphQLModule.forRoot({ + driver: ApolloDriver, + autoSchemaFile: true, + playground: process.env.NODE_ENV !== 'production', +}) +``` + +### Schema Conventions + +- Use descriptive names for queries and mutations: `createUser`, `updateProjectSettings` +- Input types end with `Input`: `CreateUserInput`, `UpdateProjectInput` +- Return the mutated object from mutations (not just a success boolean) +- Document nullable fields and their meaning + +## API Versioning + +For REST APIs with external consumers, version the API when making breaking changes: + +```typescript +// Prefix-based versioning (recommended) +@Controller({ path: 'users', version: '1' }) +export class UsersV1Controller { ... } + +@Controller({ path: 'users', version: '2' }) +export class UsersV2Controller { ... } +``` + +```typescript +// main.ts +app.enableVersioning({ + type: VersioningType.URI, // Results in /v1/users, /v2/users +}) +``` + +**When to version:** + +- Removing or renaming fields in the response +- Changing the meaning or format of existing fields +- Removing endpoints + +**When versioning is NOT needed:** + +- Adding new optional fields to responses +- Adding new endpoints +- Internal APIs consumed only by our own frontend diff --git a/docs/teams/fullstack/index.md b/docs/teams/fullstack/index.md index 77a841d4..1b2f419a 100644 --- a/docs/teams/fullstack/index.md +++ b/docs/teams/fullstack/index.md @@ -19,47 +19,50 @@ The Full-stack team is responsible for developing and maintaining our web applic - [Pull Request Guidelines](development/10_pull_request_guidelines.md) - How to create and manage pull requests - [Code Review Process](development/20_code_review_process.md) - Steps and criteria for reviewing code - [Project Setup](development/30_project_setup.md) - Steps to set up a new project +- [Technical Ownership](development/40_project_ownership.md) - Tech owner role, responsibilities, and handovers -## 🚧 Tech Stack Overview +## Tech Stack Overview -- 🚧 [Frontend](tech_stack/00_frontend.md) - Technologies used for user interfaces -- 🚧 [Backend](tech_stack/10_backend.md) - Server-side technologies and architectural patterns -- 🚧 [Database](tech_stack/20_database.md) - Data storage solutions and management practices -- 🚧 [DevOps & Infrastructure](tech_stack/30_devops.md) - Tools for deployment and infrastructure management -- 🚧 [Third-Party Integrations & APIs](tech_stack/40_integrations.md) - External services and APIs used by the team +- [Frontend](tech_stack/00_frontend.md) - Vue 3, Nuxt 3, Composition API, Pinia, Vite +- [Backend](tech_stack/10_backend.md) - NestJS architecture, REST & GraphQL patterns +- [Database](tech_stack/20_database.md) - PostgreSQL, MongoDB, ORM choices and migrations +- [DevOps & Infrastructure](tech_stack/30_devops.md) - Docker, GitHub Actions CI/CD, Terraform +- [Third-Party Integrations & APIs](tech_stack/40_integrations.md) - External services and integration patterns -## 🚧 Coding Standards +## Coding Standards - [Typescript Style Guides](coding_standards/00_style_guides.md) - Coding conventions for TypeScript - [Linting & Formatting Tools](coding_standards/10_linting.md) - Tools used to enforce code style - [Secure Coding Practices](coding_standards/20_secure_coding.md) - Guidelines for writing secure code -- 🚧 [Testing Standards](coding_standards/30_testing.md) - Approaches and tools for testing code +- [Testing Standards](coding_standards/30_testing.md) - Testing philosophy, tooling, and conventions - [Error Handling & Logging](coding_standards/40_error_handling.md) - Best practices for managing errors and logs ## Development Environment - [Local Setup Instructions](dev_env/00_local_setup.md) - Steps to get the development environment running -- [Environment Variables & Secrets Management](dev_env/10_secrets) - How to handle sensitive configuration +- [Environment Variables & Secrets Management](dev_env/10_secrets.md) - How to handle sensitive configuration +- [AI-Assisted Development](dev_env/20_ai_tools.md) - Guidelines for using AI tools effectively and safely -## 🚧 Deployment & Operations +## Deployment & Operations -- 🚧 [Deployment Process](deployment/00_deployment.md) - Steps to release code to production -- 🚧 [Rollback Procedures](deployment/10_rollback.md) - How to revert changes in case of failure -- 🚧 [Monitoring & Alerting](deployment/20_monitoring.md) - Tools and practices for tracking system health +- [Deployment Process](deployment/00_deployment.md) - CI/CD pipeline and environment promotion +- [Rollback Procedures](deployment/10_rollback.md) - How to revert changes in case of failure +- [Monitoring & Alerting](deployment/20_monitoring.md) - Observability stack and health checks +- [Operations & Access Management](deployment/30_ops.md) - Service accounts, access audits, cloud resource organization -## 🚧 Documentation +## Documentation -- 🚧 [Code Documentation Standards](docs/00_code_docs.md) - Guidelines for commenting and documenting code -- 🚧 [API Documentation](docs/10_api_docs.md) - Standards for documenting APIs +- [Code Documentation Standards](docs/00_code_docs.md) - Guidelines for documenting code and projects +- [API Documentation](docs/10_api_docs.md) - Standards for REST (Swagger) and GraphQL documentation -## 🚧 Security +## Security -- 🚧 [Authentication & Authorization](security/00_auth.md) - How users and services are authenticated and authorized -- 🚧 [Data Privacy & Compliance](security/10_privacy.md) - Policies for protecting user data and meeting regulations +- [Authentication & Authorization](security/00_auth.md) - JWT, OAuth2, guards, and token management +- [Data Privacy & Compliance](security/10_privacy.md) - GDPR, data handling, and user consent -## 🚧 Appendices +## Appendices - [Glossary of Terms](appendices/00_glossary.md) - Definitions of technical terms and acronyms -- 🚧 [Useful Scripts & Tools](appendices/10_scripts.md) - Handy scripts and utilities for daily work -- 🚧 [FAQ](appendices/20_faq.md) - Answers to frequently asked questions -- 🚧 [Templates](appendices/30_templates.md) - Reusable templates for common documents \ No newline at end of file +- [Useful Scripts & Tools](appendices/10_scripts.md) - Handy scripts and utilities for daily work +- [FAQ](appendices/20_faq.md) - Answers to frequently asked questions +- [Templates](appendices/30_templates.md) - Reusable templates for PRs, issues, READMEs, and ADRs diff --git a/docs/teams/fullstack/intro/00_mission.md b/docs/teams/fullstack/intro/00_mission.md index 3519101e..e9f6387c 100644 --- a/docs/teams/fullstack/intro/00_mission.md +++ b/docs/teams/fullstack/intro/00_mission.md @@ -6,4 +6,22 @@ We are a dedicated team of full-stack engineers focused on building and maintain - We believe in the power of open-source software and actively contribute to the community. - Technology around us is always changing, and we embrace it. We are committed to continuous learning and improvement. - Protecting user data is non-negotiable. We integrate security and privacy best practices into every stage of our development process. -- We love to experiment and push boundaries, but we do so responsibly. We balance innovation with stability, ensuring that our solutions are both cutting-edge and dependable. \ No newline at end of file +- We love to experiment and push boundaries, but we do so responsibly. We balance innovation with stability, ensuring that our solutions are both cutting-edge and dependable. + +### Defaults, Not Mandates + +This handbook defines **recommended defaults** — the tools, patterns, and processes that work well for most of our projects. They are not rigid mandates. Every project has different constraints (budget, timeline, client requirements, team expertise), and the right technical choice depends on context. + +When deviating from the defaults: + +- Document the decision and reasoning in the project README or an ADR (Architecture Decision Record) +- Discuss with the team — someone else may have experience with the alternative +- The goal is consistency where it helps and flexibility where it matters + +### Technology Awareness + +We actively track trends in AI tooling, but we recognize we need to be equally attentive to the broader IT landscape — new frameworks, infrastructure patterns, security practices, and industry shifts. To stay current: + +- **Technology radar** — We periodically review and evaluate emerging technologies as a team, assessing what to adopt, trial, or watch +- **Cross-industry awareness** — We follow developments beyond our immediate stack (other languages, cloud-native patterns, DevOps practices) +- **Sales alignment** — Our technology choices should be communicated to and aligned with the sales team, so client proposals reflect what we can deliver efficiently \ No newline at end of file diff --git a/docs/teams/fullstack/security/00_auth.md b/docs/teams/fullstack/security/00_auth.md index 0028bb2f..7163e52b 100644 --- a/docs/teams/fullstack/security/00_auth.md +++ b/docs/teams/fullstack/security/00_auth.md @@ -1,2 +1,215 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Authentication & Authorization + +This guide covers how we implement authentication (who are you?) and authorization (what can you do?) in our NestJS applications. + +## JWT-Based Authentication + +JWT (JSON Web Token) is our primary authentication mechanism for API-based applications. + +### Token Flow + +``` +1. User sends credentials (POST /auth/login) +2. Server validates credentials against the database +3. Server returns an access token (+ optional refresh token) +4. Client sends the access token in the Authorization header for subsequent requests +5. Server validates the token on each request via a guard +``` + +### NestJS Implementation + +#### Auth Module + +```typescript +// auth/auth.module.ts +@Module({ + imports: [ + UsersModule, + JwtModule.registerAsync({ + inject: [ConfigService], + useFactory: (config: ConfigService) => ({ + secret: config.getOrThrow('JWT_SECRET'), + signOptions: { expiresIn: '15m' }, + }), + }), + ], + controllers: [AuthController], + providers: [AuthService, JwtStrategy], +}) +export class AuthModule {} +``` + +#### Auth Service + +```typescript +// auth/auth.service.ts +@Injectable() +export class AuthService { + constructor( + private readonly usersService: UsersService, + private readonly jwtService: JwtService, + ) {} + + async login(dto: LoginDto): Promise { + const user = await this.usersService.findByEmail(dto.email) + if (!user || !(await bcrypt.compare(dto.password, user.passwordHash))) { + throw new UnauthorizedException('Invalid credentials') + } + + const payload: JwtPayload = { sub: user.id, email: user.email, role: user.role } + + return { + accessToken: this.jwtService.sign(payload), + refreshToken: this.jwtService.sign(payload, { expiresIn: '7d' }), + } + } +} +``` + +#### JWT Strategy (Passport) + +```typescript +// auth/strategies/jwt.strategy.ts +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor(configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + secretOrKey: configService.getOrThrow('JWT_SECRET'), + }) + } + + validate(payload: JwtPayload): JwtPayload { + return payload + } +} +``` + +### Token Storage (Frontend) + +| Storage | Pros | Cons | Use when | +|---|---|---|---| +| HTTP-only cookie | Safe from XSS | Requires CSRF protection | SSR apps, same-domain API | +| Memory (variable) | Safe from XSS and CSRF | Lost on page refresh | SPAs with refresh token flow | +| localStorage | Persists across tabs | Vulnerable to XSS | Avoid for sensitive tokens | + +**Our recommendation:** Use HTTP-only, Secure, SameSite cookies for access tokens when the API and frontend share the same domain. For cross-domain setups, use in-memory storage with a refresh token in an HTTP-only cookie. + +## OAuth2 / Social Login + +For applications that support social login: + +```typescript +// auth/strategies/google.strategy.ts +@Injectable() +export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { + constructor(configService: ConfigService) { + super({ + clientID: configService.getOrThrow('GOOGLE_CLIENT_ID'), + clientSecret: configService.getOrThrow('GOOGLE_CLIENT_SECRET'), + callbackURL: configService.getOrThrow('GOOGLE_CALLBACK_URL'), + scope: ['email', 'profile'], + }) + } + + async validate(accessToken: string, refreshToken: string, profile: Profile): Promise { + // Find or create user from Google profile + } +} +``` + +**Common providers:** + +- Google OAuth (most common) +- Apple Sign-In (required when offering social login on iOS) +- Other providers can be integrated as needed using Passport strategies (Facebook, GitHub, enterprise SSO, etc.) + +## Firebase Authentication + +For projects where we don't need custom authentication logic, we use **Firebase Authentication** as a managed solution. Firebase handles user registration, login, password resets, and social login out of the box. + +**When to use Firebase Auth:** + +- Mobile apps or projects already using Firebase services +- When rapid setup is more important than full customization +- Projects that need multiple auth providers with minimal backend code + +**Integration with NestJS:** + +```typescript +// auth/firebase-auth.guard.ts +@Injectable() +export class FirebaseAuthGuard implements CanActivate { + constructor(private readonly firebaseService: FirebaseService) {} + + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest() + const token = request.headers.authorization?.replace('Bearer ', '') + + if (!token) throw new UnauthorizedException() + + const decodedToken = await this.firebaseService.verifyIdToken(token) + request.user = decodedToken + return true + } +} +``` + +Firebase Auth can be combined with our own authorization layer (guards, roles) — Firebase handles identity, our backend handles permissions. + +## Authorization — Guards & Roles + +### Role-Based Access Control (RBAC) + +```typescript +// shared/decorators/roles.decorator.ts +export const Roles = (...roles: UserRole[]) => SetMetadata('roles', roles) + +// shared/guards/roles.guard.ts +@Injectable() +export class RolesGuard implements CanActivate { + constructor(private reflector: Reflector) {} + + canActivate(context: ExecutionContext): boolean { + const requiredRoles = this.reflector.getAllAndOverride('roles', [ + context.getHandler(), + context.getClass(), + ]) + if (!requiredRoles) return true + + const { user } = context.switchToHttp().getRequest() + return requiredRoles.includes(user.role) + } +} +``` + +### Using Guards on Endpoints + +```typescript +@Controller('admin/users') +@UseGuards(JwtAuthGuard, RolesGuard) +export class AdminUsersController { + + @Get() + @Roles(UserRole.ADMIN) + findAll(): Promise { + return this.usersService.findAll() + } + + @Delete(':id') + @Roles(UserRole.ADMIN) + remove(@Param('id') id: string): Promise { + return this.usersService.remove(id) + } +} +``` + +## Security Best Practices + +- **Hash passwords** using a strong algorithm (e.g., bcrypt with cost factor 10-12, argon2, or scrypt) — never store plaintext passwords +- **JWT secrets** must be at least 256 bits and stored in environment variables +- **Access tokens** should be short-lived (15-30 minutes) +- **Refresh tokens** should be stored securely and rotated on use +- **Rate limit** authentication endpoints to prevent brute force attacks +- **Never log** tokens, passwords, or authentication payloads +- **Invalidate sessions** on password change diff --git a/docs/teams/fullstack/security/10_privacy.md b/docs/teams/fullstack/security/10_privacy.md index 0028bb2f..56757319 100644 --- a/docs/teams/fullstack/security/10_privacy.md +++ b/docs/teams/fullstack/security/10_privacy.md @@ -1,2 +1,157 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Data Privacy & Compliance + +Protecting user data is a core responsibility. This guide covers our practices for handling personal data, complying with GDPR, and building privacy-aware applications. + +## GDPR Overview + +The General Data Protection Regulation (GDPR) applies to all projects that process personal data of EU/EEA residents — which includes most of our projects. + +### Key Principles + +- **Purpose limitation** — Collect data only for a specific, stated purpose +- **Data minimization** — Don't collect more data than needed +- **Storage limitation** — Don't keep data longer than necessary +- **Integrity and confidentiality** — Protect data from unauthorized access + +### User Rights + +Our applications must support these user rights where applicable: + +| Right | What it means | Implementation | +|---|---|---| +| Right to access | User can request a copy of their data | Export endpoint / admin panel | +| Right to rectification | User can correct inaccurate data | Edit profile / admin update | +| Right to erasure | User can request deletion of their data | Account deletion flow | +| Right to data portability | User can get their data in a machine-readable format | JSON/CSV export | + +## Data Classification + +Classify data in your application to apply appropriate protections: + +| Category | Examples | Handling | +|---|---|---| +| **PII** (Personally Identifiable Information) | Email, name, phone, address | Encrypt at rest, limit access, log access | +| **Sensitive PII** | Passwords, government IDs, health data | Encrypt at rest, never log, strict access control | +| **Non-personal** | Aggregated analytics, system logs (without PII) | Standard handling | + +## Implementation Guidelines + +### Data Collection + +```typescript +// Only collect what you need +export class CreateUserDto { + @IsEmail() + email: string // Needed for authentication + + @IsString() + name: string // Needed for display + + // Don't collect: date of birth, phone number, address + // unless the business requirement explicitly needs it +} +``` + +### Data Storage + +- **Encrypt sensitive fields** at the database level when required +- **Hash passwords** — never store plaintext (use bcrypt) +- **Separate PII** from non-sensitive data where possible (e.g., separate user profile table) + +### Data Retention + +Define retention periods for each data type: + +```typescript +// Example: Scheduled cleanup of old data +@Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT) +async cleanupExpiredData() { + // Delete unverified accounts older than 30 days + await this.usersService.deleteUnverified(30) + + // Delete audit logs older than 1 year + await this.auditService.deleteOlderThan(365) +} +``` + +**Common retention periods:** + +| Data type | Retention | Reason | +|---|---|---| +| Active user accounts | While account is active | Business need | +| Inactive accounts | 2 years after last login | Storage limitation | +| Audit logs | 1 year | Security monitoring | +| Session data | Until session expires | Functional need | +| Deleted user data | 30 days (soft delete), then purge | Recovery period | + +### Account Deletion + +When a user requests account deletion: + +1. **Soft delete** the account (mark as deleted, anonymize PII) +2. **Retain** data required by law (e.g., invoices for tax purposes) +3. **Hard delete** after the retention period expires +4. **Cascade** deletion to related entities (user's content, preferences, etc.) + +```typescript +async deleteUserAccount(userId: string): Promise { + const user = await this.usersService.findOne(userId) + + // Anonymize PII + await this.usersService.update(userId, { + email: `deleted-${userId}@anonymized.local`, + name: 'Deleted User', + deletedAt: new Date(), + }) + + // Remove from external services + await this.emailService.removeSubscriber(user.email) + await this.analyticsService.anonymizeUser(userId) +} +``` + +## Consent Management + +- **Cookie consent** — Use a cookie consent banner for analytics and marketing cookies +- **Terms of Service** — Track user acceptance with a timestamp +- **Marketing consent** — Store explicit opt-in/opt-out per communication channel + +```typescript +@Entity() +export class UserConsent { + @PrimaryGeneratedColumn('uuid') + id: string + + @ManyToOne(() => User) + user: User + + @Column() + consentType: string // 'marketing_email', 'analytics', 'terms_of_service' + + @Column() + granted: boolean + + @CreateDateColumn() + grantedAt: Date +} +``` + +## Third-Party Data Sharing + +- **Never share PII** with third parties without explicit user consent +- **Audit third-party services** for GDPR compliance before integration +- **Data Processing Agreements (DPA)** must be in place with all processors +- **Don't paste user data** into AI tools, chatbots, or external services without anonymization + +## Developer Checklist + +When building features that handle user data: + +- [ ] Only collect data that is necessary for the feature +- [ ] Document what data is collected and why +- [ ] Implement data export functionality for user access requests +- [ ] Support account deletion with proper data anonymization +- [ ] Set up data retention policies and automated cleanup +- [ ] Never log PII (emails, names, tokens) in application logs +- [ ] Ensure third-party services have DPAs in place +- [ ] Include privacy considerations in code reviews diff --git a/docs/teams/fullstack/tech_stack/00_frontend.md b/docs/teams/fullstack/tech_stack/00_frontend.md index 0028bb2f..0c19326a 100644 --- a/docs/teams/fullstack/tech_stack/00_frontend.md +++ b/docs/teams/fullstack/tech_stack/00_frontend.md @@ -1,2 +1,170 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Frontend + +Our frontend stack is built around Vue 3, Nuxt 3, and TypeScript. We prioritize type safety, developer experience, and performance. + +## Architecture Overview + +![](./Resources/00_frontend_arch_light.png#only-light){data-gallery="light"} +![](./Resources/00_frontend_arch_dark.png#only-dark){data-gallery="dark"} + +## Core Technologies + +### Vue 3 + Composition API + +Vue 3 with the Composition API is our primary UI framework. We use ` + + +``` + +**Why Vue:** + +- Gentle learning curve with progressive adoption +- Excellent TypeScript integration with the Composition API +- Strong ecosystem (Nuxt, Pinia, VueUse, DevTools) +- Performant reactivity system with fine-grained updates +- Active community and long-term maintenance by a dedicated core team + +### Nuxt 3 + +Nuxt 3 is our default framework for Vue applications. It provides a production-ready foundation with conventions that reduce decision fatigue and boilerplate. + +![](./Resources/00_frontend_nuxt_rendering_light.png#only-light){data-gallery="light"} +![](./Resources/00_frontend_nuxt_rendering_dark.png#only-dark){data-gallery="dark"} + + +**Key capabilities:** + +- **Server-side rendering** — Fast initial page loads and SEO for public-facing apps +- **File-based routing** — Pages are automatically generated from the `pages/` directory +- **Auto-imports** — Vue APIs, composables, and components are available without manual imports +- **Server routes** — Lightweight backend endpoints within the Nuxt app (`server/api/`) +- **Module ecosystem** — Rich set of official and community modules for common needs + +**When to use Nuxt:** + +- Public-facing applications that benefit from SSR/SEO +- Admin panels and dashboards (using SPA mode) +- Any new Vue project — Nuxt's conventions reduce boilerplate + +**When plain Vue (Vite) is sufficient:** + +- Embedded widgets or micro-frontends +- Simple single-page apps with no routing needs + +### TypeScript + +All frontend code is written in TypeScript with strict mode enabled. API types are inferred from the backend via code generation — we don't manually write types for API responses. + +**TypeScript benefits in our stack:** + +- Catches errors at compile time, before they reach production +- Enables IDE auto-completion and refactoring across the entire codebase +- API types are auto-generated from the backend schema (OpenAPI/GraphQL codegen), ensuring frontend and backend stay in sync +- Types serve as living documentation — when the API changes, the generated types break at compile time, not at runtime + +## State Management + +### Pinia + +Pinia is our state management library. It integrates natively with Vue's reactivity system and supports TypeScript out of the box. + +```typescript +// stores/auth.ts +export const useAuthStore = defineStore('auth', () => { + const user = ref(null) + const isAuthenticated = computed(() => !!user.value) + + async function login(credentials: LoginDto) { + const response = await $fetch('/api/auth/login', { + method: 'POST', + body: credentials, + }) + user.value = response + } + + function logout() { + user.value = null + navigateTo('/login') + } + + return { user, isAuthenticated, login, logout } +}) +``` + +**Guidelines:** + +- One store per domain concern (auth, users, settings) +- Use composable-style stores (setup function syntax) +- Keep stores thin — business logic belongs in composables or API layers + +## Data Flow + +![](./Resources/00_frontend_data_flow_light.png#only-light){data-gallery="light"} +![](./Resources/00_frontend_data_flow_dark.png#only-dark){data-gallery="dark"} + +## Build Tooling + +### Vite + +Vite is the underlying build tool for both Vue and Nuxt projects. It provides: + +- **Instant HMR** — Changes reflect in the browser in milliseconds during development +- **Optimized builds** — Tree-shaking, code splitting, and asset optimization for production +- **Plugin ecosystem** — Extensible via Rollup-compatible plugins + +### Project Structure + +``` +project/ +├── pages/ # File-based routing +│ ├── index.vue # → / +│ ├── login.vue # → /login +│ └── users/ +│ ├── index.vue # → /users +│ └── [id].vue # → /users/:id +├── components/ # Auto-imported components +│ ├── AppHeader.vue +│ └── UserCard.vue +├── composables/ # Shared reactive logic +│ ├── useAuth.ts +│ └── useUsers.ts +├── stores/ # Pinia state management +│ └── auth.ts +├── layouts/ # Page layouts +│ └── default.vue +├── middleware/ # Route middleware +│ └── auth.ts +├── plugins/ # Nuxt plugins (Sentry, etc.) +├── server/ # Server routes and middleware +│ └── api/ +├── types/ # TypeScript type definitions +└── nuxt.config.ts # Nuxt configuration +``` + +### Key Conventions + +- **Auto-imports**: Nuxt auto-imports Vue APIs and composables — no need for manual imports in most cases +- **CSS**: Use scoped styles in components. For shared styles, use a CSS framework or utility classes as appropriate for the project +- **API calls**: Use Nuxt's `$fetch` or `useFetch` composable for data fetching with built-in SSR support + +## Browser Support + +We target modern evergreen browsers (Chrome, Firefox, Safari, Edge — latest 2 versions). IE11 is not supported. diff --git a/docs/teams/fullstack/tech_stack/10_backend.md b/docs/teams/fullstack/tech_stack/10_backend.md index 0028bb2f..9963a5ea 100644 --- a/docs/teams/fullstack/tech_stack/10_backend.md +++ b/docs/teams/fullstack/tech_stack/10_backend.md @@ -1,2 +1,218 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Backend + +Our backend stack is built on NestJS with Node.js, supporting both REST and GraphQL APIs. We emphasize modular architecture, type safety, and testability. + +## Architecture Overview + +![](./Resources/10_backend_arch_overview_light.png#only-light){data-gallery="light"} +![](./Resources/10_backend_arch_overview_dark.png#only-dark){data-gallery="dark"} + +## Core Technologies + +### NestJS + +NestJS is our primary backend framework. It provides a structured, opinionated architecture with first-class TypeScript support, dependency injection, and a modular design that scales from small APIs to complex applications. + +**Why NestJS:** + +- **Modular architecture** — Encourages separation of concerns and code reuse across projects +- **Dependency injection** — Built-in IoC container for clean, testable service composition +- **Protocol agnostic** — Same codebase can serve REST, GraphQL, WebSockets, and gRPC +- **Rich ecosystem** — First-party packages for auth, config, caching, queues, scheduling, and more +- **TypeScript native** — Designed from the ground up for TypeScript, not retrofitted +- **Enterprise-grade** — Battle-tested patterns for validation, error handling, logging, and security + +**Trade-offs to consider:** + +- NestJS adds abstraction overhead — for simple APIs, this can mean higher development cost for clients +- The learning curve is steeper compared to plain Express/Fastify +- Some client budgets or project scopes don't justify the full NestJS setup + +### Choosing a Backend Framework + +NestJS is the **default**, not a mandate. For projects where NestJS is overkill, consider lighter alternatives: + +| Framework | When to use | +|---|---| +| **NestJS** | Medium-to-large projects, complex business logic, multiple modules, long-term maintenance | +| **Express / Fastify** | Small APIs, microservices, tight budgets, simple CRUD | +| **Hono** | Edge-first APIs, serverless functions, minimal footprint | + +The decision should be made at project kickoff based on scope, budget, and expected complexity. Document the choice in the project README. + +### Request Lifecycle + +Every incoming request passes through a well-defined pipeline of NestJS components: + +![](./Resources/10_backend_request_lifecycle_light.png#only-light){data-gallery="light"} +![](./Resources/10_backend_request_lifecycle_dark.png#only-dark){data-gallery="dark"} + + +Each layer has a clear responsibility: + +| Layer | Responsibility | Example | +|---|---|---| +| **Middleware** | Request preprocessing | CORS, body parsing, request logging | +| **Guards** | Authentication & authorization | JWT validation, role checks | +| **Interceptors** | Cross-cutting concerns | Response mapping, caching, timing | +| **Pipes** | Data validation & transformation | DTO validation, type coercion | +| **Controllers/Resolvers** | Route handling | Map HTTP/GraphQL requests to services | +| **Services** | Business logic | Core application functionality | +| **Filters** | Error handling | Standardized error responses | + +### Module Structure + +Every NestJS project follows a modular architecture: + +``` +src/ +├── app.module.ts # Root module +├── shared/ # Shared utilities, guards, interceptors +│ ├── guards/ +│ ├── interceptors/ +│ ├── filters/ +│ └── decorators/ +├── config/ # Configuration and validation +├── auth/ # Authentication module +│ ├── auth.module.ts +│ ├── auth.service.ts +│ ├── auth.controller.ts +│ └── strategies/ +├── users/ # Feature module +│ ├── users.module.ts +│ ├── users.service.ts +│ ├── users.controller.ts (REST) or users.resolver.ts (GraphQL) +│ ├── dto/ +│ └── entities/ +└── ... +``` + +**Guidelines:** + +- One module per domain entity or feature area +- Modules expose only what's needed via `exports` +- Shared logic goes in `shared/` +- Configuration is validated at startup using `@nestjs/config` with Zod or class-validator + +## API Patterns + +### REST + +For standard CRUD operations and simple APIs, we use REST controllers: + +```typescript +@Controller('users') +export class UsersController { + constructor(private readonly usersService: UsersService) {} + + @Get() + findAll(@Query() query: PaginationDto): Promise> { + return this.usersService.findAll(query) + } + + @Get(':id') + findOne(@Param('id', ParseUUIDPipe) id: string): Promise { + return this.usersService.findOne(id) + } + + @Post() + create(@Body() dto: CreateUserDto): Promise { + return this.usersService.create(dto) + } +} +``` + +### GraphQL + +For complex data requirements or when the frontend needs flexible queries, we use GraphQL with the code-first approach: + +```typescript +@Resolver(() => User) +export class UsersResolver { + constructor(private readonly usersService: UsersService) {} + + @Query(() => [User]) + async users(): Promise { + return this.usersService.findAll() + } + + @Mutation(() => User) + async createUser(@Args('input') input: CreateUserInput): Promise { + return this.usersService.create(input) + } + + @ResolveField(() => [Project]) + async projects(@Parent() user: User): Promise { + return this.usersService.getProjects(user.id) + } +} +``` + +### Choosing an API Style + +**REST is the default.** GraphQL adds complexity (schema management, N+1 queries, caching challenges) and should only be used when its benefits clearly outweigh the cost. + +![](./Resources/10_backend_rest_vs_graphql_light.png#only-light){data-gallery="light"} +![](./Resources/10_backend_rest_vs_graphql_dark.png#only-dark){data-gallery="dark"} + + +| Use REST when... | Use GraphQL when... | +|---|---| +| Simple CRUD operations | Complex nested data relationships | +| Public APIs for third parties | Frontend needs flexible queries | +| File uploads / downloads | Multiple related entities per request | +| Webhooks and callbacks | Real-time subscriptions needed | +| **Most projects (default)** | **Only when justified by data complexity** | + +!!! info "GraphQL Considerations" + + GraphQL is powerful but adds operational cost: schema versioning, query complexity limits, caching strategies, and tooling overhead. Don't adopt it just because it's modern — adopt it when the frontend genuinely benefits from flexible queries over multiple related entities. + +## Validation + +All incoming data is validated using DTOs with `class-validator`: + +```typescript +// dto/create-user.dto.ts +export class CreateUserDto { + @IsEmail() + email: string + + @IsString() + @MinLength(2) + @MaxLength(100) + name: string + + @IsEnum(UserRole) + role: UserRole +} +``` + +## Architecture: Monolith vs. Services + +**Start with a modular monolith.** Only split into dedicated services when there is a clear, justified need. + +| Approach | When to use | +|---|---| +| **Modular monolith** | Most projects. Single deployable, modules separated by NestJS module boundaries. Simpler ops, easier debugging. | +| **Dedicated services** | When parts of the system have fundamentally different scaling, deployment, or team ownership needs. | + +**Signs you need to split:** + +- One part of the system needs independent scaling (e.g. heavy background processing) +- Different release cadences for different parts +- Separate teams owning separate domains +- A module's failure should not bring down the rest + +**Rules for services:** + +- Each service owns its data — no shared databases +- Services communicate via REST APIs or message queues, not direct DB access +- Every service must be independently deployable and have its own CI/CD pipeline +- Document service boundaries and communication contracts + +## Node.js Runtime + +- We use the LTS version of Node.js specified in each project's `.nvmrc` +- Package manager: **yarn** (primary) — some projects may use npm +- All projects include `engines` field in `package.json` to enforce Node.js version diff --git a/docs/teams/fullstack/tech_stack/20_database.md b/docs/teams/fullstack/tech_stack/20_database.md index 0028bb2f..332cfb07 100644 --- a/docs/teams/fullstack/tech_stack/20_database.md +++ b/docs/teams/fullstack/tech_stack/20_database.md @@ -1,2 +1,122 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Database + +We use PostgreSQL as our primary relational database and MongoDB for specific use cases. Database access is primarily through an ORM or query builder. Raw SQL queries are acceptable when the query is too complex to express cleanly with the ORM. + +## Data Architecture + +![](./Resources/20_database_data_architecture_light.png#only-light){data-gallery="light"} +![](./Resources/20_database_data_architecture_dark.png#only-dark){data-gallery="dark"} + + +## PostgreSQL + +PostgreSQL is the default choice for all new projects. It provides strong ACID compliance, excellent JSON support, and a rich feature set that covers the vast majority of our data requirements. + +**Why PostgreSQL:** + +- **Reliability** — Proven in production at scale across thousands of organizations worldwide +- **ACID compliance** — Full transactional support with referential integrity +- **Rich data types** — Native JSON/JSONB, arrays, enums, UUID, and more +- **Performance** — Advanced query planner, indexing strategies, and parallel query execution +- **Extensibility** — Full-text search, PostGIS for geospatial data, and a rich extension ecosystem +- **Managed hosting** — Available as a managed service on both GCP (Cloud SQL) and Digital Ocean + +**When we use PostgreSQL:** + +- Structured, relational data with well-defined schemas +- Applications requiring transactions and referential integrity +- Most CRUD-based projects (which covers the majority of our work) + +## MongoDB + +MongoDB is used in projects where the data model is inherently document-oriented or when working with highly variable schemas. + +**When we use MongoDB:** + +- Document-oriented data (CMS content, logs, event streams) +- Rapidly evolving schemas during prototyping +- When explicitly required by a project's data model + +## ORM Choices + +### TypeORM + +TypeORM is our most commonly used ORM, with deep NestJS integration via `@nestjs/typeorm`. + +```typescript +// entities/user.entity.ts +@Entity() +export class User { + @PrimaryGeneratedColumn('uuid') + id: string + + @Column({ unique: true }) + email: string + + @Column() + name: string + + @CreateDateColumn() + createdAt: Date + + @OneToMany(() => Project, (project) => project.owner) + projects: Project[] +} +``` + +### Prisma & Drizzle (Experimental) + +We are experimenting with **Prisma** and **Drizzle** in prototypes and internal projects. Neither is currently used in production. + +- **Prisma** — Type-safe query API, schema-first approach, excellent migration tooling +- **Drizzle** — Lightweight, SQL-like control with full type safety and minimal overhead + +These may become recommended alternatives in the future as we gain more experience with them in real projects. + +## Migration Strategy + +Database schema changes are always managed through migrations — never manual DDL. + +![](./Resources/20_database_migration_strategy_light.png#only-light){data-gallery="light"} +![](./Resources/20_database_migration_strategy_dark.png#only-dark){data-gallery="dark"} + + +### Rules + +1. **Every schema change gets a migration** — no exceptions +2. **Migrations are committed to version control** alongside the code that uses them +3. **Migrations run automatically** in CI/CD before the application starts +4. **Never edit an existing migration** that has been applied to any environment +5. **Test migrations** against a copy of production data when possible + +### Example: Prisma Migrations + +```bash +# Create a migration after changing schema.prisma +npx prisma migrate dev --name add_user_role + +# Apply migrations in production +npx prisma migrate deploy +``` + +### Example: TypeORM Migrations + +```bash +# Generate a migration from entity changes +npx typeorm migration:generate -n AddUserRole + +# Run pending migrations +npx typeorm migration:run +``` + +## Connection Management + +- Use connection pooling (configured in the ORM or via PgBouncer for high-traffic apps) +- Set reasonable pool sizes: `min: 2, max: 10` for development, adjust for production based on load +- Always close connections gracefully on app shutdown + +## Backups + +- **Production**: Automated daily backups via the hosting provider (GCP Cloud SQL / Digital Ocean Managed Database) +- **Staging**: Weekly backups or on-demand snapshots +- **Development**: No backups needed — use seed scripts to recreate data diff --git a/docs/teams/fullstack/tech_stack/30_devops.md b/docs/teams/fullstack/tech_stack/30_devops.md index 0028bb2f..f9fbeb01 100644 --- a/docs/teams/fullstack/tech_stack/30_devops.md +++ b/docs/teams/fullstack/tech_stack/30_devops.md @@ -1,2 +1,172 @@ -!!! warning "Work in progress" - \ No newline at end of file +# DevOps & Infrastructure + +Our infrastructure is containerized, automated, and deployed via CI/CD pipelines. We run on Google Cloud Platform (GCP) and Digital Ocean, sometimes managed with Terraform. + +## Infrastructure Overview + +![](./Resources/30_devops_infrastructure_overview_light.png#only-light){data-gallery="light"} +![](./Resources/30_devops_infrastructure_overview_dark.png#only-dark){data-gallery="dark"} + +## Docker + +Every project is containerized for both development and production. + +### Development + +We use Docker Compose for local development environments: + +```yaml +# docker-compose.dist.yml +services: + api: + build: + context: ./api + dockerfile: dev.Dockerfile + volumes: + - ./api/src:/app/src + ports: + - "8080:8080" + depends_on: + - postgres + - cache + + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: myapp + POSTGRES_USER: myapp + POSTGRES_PASSWORD: localdev + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + + cache: + image: redis:7-alpine + ports: + - "6379:6379" + +volumes: + pgdata: +``` + +### Production + +Production containers use multi-stage builds for minimal image size: + +```dockerfile +# Build stage +FROM node:20-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# Production stage +FROM node:20-alpine +WORKDIR /app +COPY --from=builder /app/dist ./dist +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/package.json ./ + +EXPOSE 8080 +CMD ["node", "dist/main.js"] +``` + +## CI/CD Pipeline + +All projects use GitHub Actions for continuous integration and deployment. The specific workflow varies per project, but the process follows the same stages: + +![](./Resources/30_devops_cicd_pipeline_light.png#only-light){data-gallery="light"} +![](./Resources/30_devops_cicd_pipeline_dark.png#only-dark){data-gallery="dark"} + + +1. **Lint** — ESLint + Prettier checks ensure code quality +2. **Test** — Unit and integration tests verify functionality +3. **Build** — TypeScript compilation and Docker image build verify everything compiles +4. **Push** — Docker image is tagged with the commit SHA and pushed to the container registry +5. **Deploy** — The new image is deployed to the target environment + +See [Deployment Process](../deployment/00_deployment.md) for detailed deployment procedures. + +## Hosting Platforms + +### Google Cloud Platform (GCP) + +Used for larger or more complex projects: + +- **Cloud Run** — Serverless container hosting (primary compute) +- **Cloud SQL** — Managed PostgreSQL +- **Cloud Storage** — File storage and static assets +- **Secret Manager** — Secrets management +- **Cloud Build** — Container image builds (alternative to GitHub Actions) + +### Digital Ocean + +Used for smaller projects or when simpler infrastructure is preferred: + +- **App Platform** — Container and static site hosting +- **Managed Database** — PostgreSQL and Redis +- **Spaces** — Object storage (S3-compatible) + +### Choosing a Platform + +![](./Resources/30_devops_hosting_platform_light.png#only-light){data-gallery="light"} +![](./Resources/30_devops_hosting_platform_dark.png#only-dark){data-gallery="dark"} + + +| | GCP | Digital Ocean | +|---|---|---| +| Best for | Complex apps, scaling needs, enterprise clients | Simpler apps, tighter budgets, quick setup | +| Pricing model | Pay-per-use | Predictable monthly pricing | +| Managed services | Extensive (50+ services) | Focused (core services) | +| Terraform support | Full | Full | + +The choice is made per project based on client requirements, budget, and complexity. + +## Infrastructure as Code + +!!! warning "Current State" + + Most projects today do **not** use Infrastructure as Code. Infrastructure is typically set up manually through cloud provider consoles and CLI tools. This is a known gap and one of the team's top priorities to improve. + +### Where We Are + +- Infrastructure for most projects is provisioned manually (cloud consoles, CLI) +- A handful of projects use **Terraform** with basic GCP or Digital Ocean resource definitions +- There is no standardized IaC template or workflow across projects +- Manual setup leads to inconsistent environments, undocumented configuration, and difficult handovers + +### Where We Want to Be + +Our goal is to adopt **Pulumi** as the primary IaC tool. Pulumi allows defining infrastructure in TypeScript, which fits naturally into our stack and lowers the barrier for full-stack developers. + +**Target state:** + +- Every new project includes a Pulumi stack defining its cloud resources +- Infrastructure changes go through PR review, just like application code +- Infrastructure state is stored remotely (Pulumi Cloud or GCS bucket) +- Environment-specific configuration is separated from resource definitions +- Project audits to migrate existing manual infrastructure to code + +### Transition Plan + +1. **New projects** — Start with a Pulumi template as part of project scaffolding +2. **Existing projects** — Gradually import existing resources into Pulumi during maintenance windows +3. **Knowledge sharing** — OPS specialists help teams adopt IaC practices + +## Environment Promotion + +Code flows through environments in this order: + +![](./Resources/30_devops_environment_promotion_light.png#only-light){data-gallery="light"} +![](./Resources/30_devops_environment_promotion_dark.png#only-dark){data-gallery="dark"} + + +Each environment has its own: + +- Database instance +- Environment variables and secrets +- Domain / URL +- Resource allocation (dev uses smaller instances) diff --git a/docs/teams/fullstack/tech_stack/40_integrations.md b/docs/teams/fullstack/tech_stack/40_integrations.md index 0028bb2f..59ee93df 100644 --- a/docs/teams/fullstack/tech_stack/40_integrations.md +++ b/docs/teams/fullstack/tech_stack/40_integrations.md @@ -1,2 +1,131 @@ -!!! warning "Work in progress" - \ No newline at end of file +# Third-Party Integrations & APIs + +This page documents common third-party services we integrate with and the patterns we follow for clean, maintainable integrations. + +## Integration Architecture + +![](./Resources/40_integrations_arch_light.png#only-light){data-gallery="light"} +![](./Resources/40_integrations_arch_dark.png#only-dark){data-gallery="dark"} + +## Integration Patterns + +### Wrapping External Services + +Always wrap third-party services in a dedicated NestJS module. This isolates external dependencies and makes them easy to swap or mock. + +```typescript +// integrations/email/email.module.ts +@Module({ + providers: [EmailService], + exports: [EmailService], +}) +export class EmailModule {} + +// integrations/email/email.service.ts +@Injectable() +export class EmailService { + constructor(private readonly configService: ConfigService) {} + + async sendEmail(to: string, template: string, data: Record): Promise { + // Provider-specific implementation + } +} +``` + +**Why wrap:** + +- Feature modules depend on `EmailService`, not on a specific provider +- Switching from one email provider to another only changes one file +- Easy to mock in tests + +### Integration Flow + +![](./Resources/40_integrations_flow_light.png#only-light){data-gallery="light"} +![](./Resources/40_integrations_flow_dark.png#only-dark){data-gallery="dark"} + +### Configuration + +All integration credentials are managed as environment variables, never hardcoded: + +```typescript +// integrations/storage/storage.service.ts +@Injectable() +export class StorageService { + private readonly bucket: string + + constructor(private readonly configService: ConfigService) { + this.bucket = this.configService.getOrThrow('STORAGE_BUCKET') + } +} +``` + +## Common Integrations + +### Email + +- **Resend** — Transactional emails, our primary email provider +- **OneSignal** — Email and push notification platform + +Emails are sent via API, not SMTP. We use templates managed in the email provider's dashboard or in-code with MJML/HTML. + +### File Storage + +- **GCP Cloud Storage** — For GCP-hosted projects +- **Digital Ocean Spaces** — S3-compatible, for DO-hosted projects +- **AWS S3** — When the client's infrastructure is on AWS + +```typescript +// Common pattern: generate signed upload URLs +async getUploadUrl(fileName: string): Promise { + const key = `uploads/${Date.now()}-${fileName}` + return this.storage.getSignedUrl(key, { + action: 'write', + expires: Date.now() + 15 * 60 * 1000, // 15 minutes + contentType: 'application/octet-stream', + }) +} +``` + +### Payments + +- **Stripe** — Primary payment processor +- **GoPay** — Used for Czech/Slovak market projects + +![](./Resources/40_integrations_stripe_payment_light.png#only-light){data-gallery="light"} +![](./Resources/40_integrations_stripe_payment_dark.png#only-dark){data-gallery="dark"} + +For payments, we always: + +1. Use webhooks to confirm payment status (never trust client-side callbacks alone) +2. Store payment events in our database for auditability +3. Implement idempotency keys for retry safety + +### Authentication Providers + +- **Google OAuth** — Most common social login +- **Apple Sign-In** — Required for iOS apps with social login +- **Firebase Auth** — Managed authentication for projects that don't need custom auth logic + +See [Authentication & Authorization](../security/00_auth.md) for implementation details. + +### Analytics & Monitoring + +- **Sentry** — Error tracking and performance monitoring (see [Monitoring](../deployment/20_monitoring.md)) +- **Google Analytics** — Web analytics (frontend) +- **Mixpanel / PostHog** — Product analytics when needed + +### Communication + +- **Slack API** — Build notifications, deployment alerts, CI/CD integration +- **Firebase Cloud Messaging (FCM)** — Push notifications for mobile and web apps + +## Integration Checklist + +When adding a new third-party integration: + +- [ ] Create a dedicated module in `src/integrations//` +- [ ] Add required environment variables to `docker-compose.dist.yml` and `.env.example` +- [ ] Document the integration in the project README +- [ ] Add error handling for API failures (retries, circuit breakers for critical paths) +- [ ] Write integration tests with mocked responses +- [ ] Verify the service has acceptable uptime SLAs for production use diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch.md b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch.md new file mode 100644 index 00000000..a5055e9e --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch.md @@ -0,0 +1,41 @@ +```mermaid +graph TB + subgraph Browser["Browser"] + UI([Vue Components]) + Store([Pinia Stores]) + Composables([Composables]) + Router([Nuxt Router]) + end + + subgraph Nuxt["Nuxt Layer"] + SSR{{SSR / SPA Engine}} + Middleware{{Route Middleware}} + Plugins{{Plugins}} + ServerRoutes{{Server Routes / API Proxy}} + end + + subgraph External["External Services"] + API[(Backend API)] + Auth>Auth Provider] + CDN>Static Assets / CDN] + end + + UI --> Store + UI --> Composables + Router --> Middleware --> UI + Plugins --> UI + SSR --> UI + Composables --> ServerRoutes + ServerRoutes --> API + Store --> API + UI --> Auth + UI --> CDN + + classDef browser fill:#42b883,stroke:#35495e,color:#fff + classDef nuxt fill:#00dc82,stroke:#003c1c,color:#003c1c + classDef external fill:#3b82f6,stroke:#1e40af,color:#fff + + class UI,Store,Composables,Router browser + class SSR,Middleware,Plugins,ServerRoutes nuxt + class API,Auth,CDN external +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_dark.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_dark.png new file mode 100644 index 00000000..31c990b4 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_light.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_light.png new file mode 100644 index 00000000..e15d7f50 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_arch_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow.md b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow.md new file mode 100644 index 00000000..4e8bdaa0 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow.md @@ -0,0 +1,20 @@ +```mermaid +sequenceDiagram + actor User + participant Component as Vue Component + participant Composable as Composable / Store + participant API as Backend API + + User->>Component: Interaction (click, input) + activate Component + Component->>Composable: Call action + activate Composable + Composable->>API: $fetch / useFetch + activate API + API-->>Composable: JSON response + deactivate API + Composable-->>Component: Reactive state update + deactivate Composable + Component-->>User: UI update + deactivate Component +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_dark.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_dark.png new file mode 100644 index 00000000..4507b242 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_light.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_light.png new file mode 100644 index 00000000..88933ee6 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_data_flow_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering.md b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering.md new file mode 100644 index 00000000..d86bfa90 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering.md @@ -0,0 +1,11 @@ +```mermaid +graph LR + SSR_MODE([SSR
Server-Side Rendering]):::ssr -->|"SEO, public pages,
fast first paint"| USE_SSR[/Public-facing apps
Marketing sites
E-commerce/]:::usecase + SPA_MODE([SPA
Single Page Application]):::spa -->|"Rich interactivity,
no SEO needs"| USE_SPA[/Admin panels
Dashboards
Internal tools/]:::usecase + SSG_MODE([SSG
Static Site Generation]):::ssg -->|"Pre-rendered
at build time"| USE_SSG[/Documentation
Landing pages
Blogs/]:::usecase + + classDef ssr fill:#42b883,stroke:#35495e,color:#fff + classDef spa fill:#3b82f6,stroke:#1e40af,color:#fff + classDef ssg fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef usecase fill:#f1f5f9,stroke:#94a3b8,color:#334155 +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_dark.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_dark.png new file mode 100644 index 00000000..3534b2f0 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_light.png b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_light.png new file mode 100644 index 00000000..e3f4a0fe Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/00_frontend_nuxt_rendering_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview.md b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview.md new file mode 100644 index 00000000..100e4e81 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview.md @@ -0,0 +1,54 @@ +```mermaid +graph TB + subgraph Clients["Client Layer"] + Web([Web App / SPA]):::client + Mobile([Mobile App]):::client + External([External Consumer]):::client + end + + subgraph API["API Layer"] + Gateway{{API Gateway / Load Balancer}}:::gateway + REST[/REST Controllers/]:::api + GQL[/GraphQL Resolvers/]:::api + end + + subgraph App["Application Layer"] + Guards[[Guards & Middleware]]:::app + Pipes[[Validation Pipes]]:::app + Services[[Business Logic]]:::app + Interceptors[[Interceptors & Filters]]:::app + end + + subgraph Data["Data Layer"] + ORM([ORM — Prisma / TypeORM]):::data + Cache[(Redis Cache)]:::data + ExtAPI>External APIs]:::data + end + + subgraph Storage["Storage"] + DB[(PostgreSQL)]:::storage + FileStore[(Cloud Storage)]:::storage + end + + Web --> Gateway + Mobile --> Gateway + External --> Gateway + Gateway --> Guards + Guards --> REST + Guards --> GQL + REST --> Pipes --> Services + GQL --> Pipes --> Services + Services --> Interceptors + Services --> ORM + Services --> Cache + Services --> ExtAPI + ORM --> DB + Services --> FileStore + + classDef client fill:#64748b,stroke:#334155,color:#fff + classDef gateway fill:#f59e0b,stroke:#b45309,color:#fff + classDef api fill:#e11d48,stroke:#9f1239,color:#fff + classDef app fill:#3b82f6,stroke:#1e40af,color:#fff + classDef data fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef storage fill:#059669,stroke:#065f46,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_dark.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_dark.png new file mode 100644 index 00000000..c52ad8a6 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_light.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_light.png new file mode 100644 index 00000000..0148e825 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_arch_overview_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle.md b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle.md new file mode 100644 index 00000000..fa9ad3c9 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle.md @@ -0,0 +1,35 @@ +```mermaid +graph TD + subgraph row1[" "] + direction LR + Request([Incoming Request]):::req --> Middleware[[Middleware]]:::mid + Middleware --> Guards[[Guards
Auth & Roles]]:::guard + Guards --> Interceptors_Pre[[Interceptors
Pre-processing]]:::inter + Interceptors_Pre --> Pipes[[Pipes
Validation]]:::pipe + end + + subgraph row2[" "] + direction LR + Handler[/Controller / Resolver
Route Handler/]:::handler --> Service([Service
Business Logic]):::service + Service --> Interceptors_Post[[Interceptors
Post-processing]]:::inter + Interceptors_Post --> Filters{Exception?}:::decision + Filters -->|No| Response([Response]):::success + Filters -->|Yes| ExFilter[[Exception Filter]]:::error + end + + Pipes --> Handler + + classDef req fill:#64748b,stroke:#334155,color:#fff + classDef mid fill:#f59e0b,stroke:#b45309,color:#fff + classDef guard fill:#e11d48,stroke:#9f1239,color:#fff + classDef inter fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef pipe fill:#3b82f6,stroke:#1e40af,color:#fff + classDef handler fill:#06b6d4,stroke:#0e7490,color:#fff + classDef service fill:#059669,stroke:#065f46,color:#fff + classDef decision fill:#f59e0b,stroke:#b45309,color:#fff + classDef success fill:#22c55e,stroke:#15803d,color:#fff + classDef error fill:#ef4444,stroke:#b91c1c,color:#fff + + style row1 fill:none,stroke:none + style row2 fill:none,stroke:none +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_dark.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_dark.png new file mode 100644 index 00000000..45ebaa28 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_light.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_light.png new file mode 100644 index 00000000..86240431 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_request_lifecycle_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql.md b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql.md new file mode 100644 index 00000000..caff811c --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql.md @@ -0,0 +1,14 @@ +```mermaid +graph TD + Start{New API Endpoint?}:::decision --> Q1{Complex nested data?
Flexible queries needed?}:::decision + Q1 -->|Yes| GraphQL([Use GraphQL]):::graphql + Q1 -->|No| Q2{File uploads?
Webhooks? Public API?}:::decision + Q2 -->|Yes| REST([Use REST]):::rest + Q2 -->|No| Q3{Real-time subscriptions?}:::decision + Q3 -->|Yes| GraphQL + Q3 -->|No| REST + + classDef decision fill:#f59e0b,stroke:#b45309,color:#fff + classDef rest fill:#3b82f6,stroke:#1e40af,color:#fff + classDef graphql fill:#e11d48,stroke:#9f1239,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_dark.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_dark.png new file mode 100644 index 00000000..8de433c1 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_light.png b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_light.png new file mode 100644 index 00000000..795d9798 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/10_backend_rest_vs_graphql_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture.md b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture.md new file mode 100644 index 00000000..353cbcd9 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture.md @@ -0,0 +1,32 @@ +```mermaid +graph TB + subgraph Application["Application"] + Service([NestJS Service]):::app + ORM{{ORM Layer
Prisma / TypeORM}}:::orm + end + + subgraph DataStorage["Data Storage"] + PG[(PostgreSQL
Primary Database)]:::pg + Mongo[(MongoDB
Document Store)]:::mongo + Redis[(Redis
Cache & Sessions)]:::redis + end + + subgraph Managed["Managed Services"] + CloudSQL[/GCP Cloud SQL
DO Managed DB/]:::managed + Backups[/Automated Backups
Point-in-Time Recovery/]:::managed + end + + Service --> ORM + ORM --> PG + ORM --> Mongo + Service --> Redis + PG --> CloudSQL + CloudSQL --> Backups + + classDef app fill:#3b82f6,stroke:#1e40af,color:#fff + classDef orm fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef pg fill:#336791,stroke:#1e3a5f,color:#fff + classDef mongo fill:#4db33d,stroke:#2d6e23,color:#fff + classDef redis fill:#dc382d,stroke:#a02a22,color:#fff + classDef managed fill:#f59e0b,stroke:#b45309,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_dark.png b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_dark.png new file mode 100644 index 00000000..a817b6de Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_light.png b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_light.png new file mode 100644 index 00000000..f6ebde5a Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/20_database_data_architecture_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy.md b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy.md new file mode 100644 index 00000000..afc17aca --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy.md @@ -0,0 +1,15 @@ +```mermaid +graph LR + Change([Schema Change
in Code]):::code --> Migration{{Generate
Migration File}}:::migration + Migration --> Review[[Code Review
in PR]]:::review + Review --> CI[[CI Runs
Migration Test]]:::ci + CI --> Deploy([Deploy:
Run Migration]):::deploy + Deploy --> App([Start
Application]):::success + + classDef code fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef migration fill:#3b82f6,stroke:#1e40af,color:#fff + classDef review fill:#f59e0b,stroke:#b45309,color:#fff + classDef ci fill:#06b6d4,stroke:#0e7490,color:#fff + classDef deploy fill:#e11d48,stroke:#9f1239,color:#fff + classDef success fill:#22c55e,stroke:#15803d,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_dark.png b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_dark.png new file mode 100644 index 00000000..efd0281c Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_light.png b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_light.png new file mode 100644 index 00000000..e5e2b162 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/20_database_migration_strategy_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline.md b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline.md new file mode 100644 index 00000000..bba835bc --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline.md @@ -0,0 +1,21 @@ +```mermaid +graph LR + subgraph CI["CI — Every PR"] + Lint([Lint
ESLint + Prettier]):::lint --> Test([Test
Unit + Integration]):::test + Test --> Build([Build
TypeScript + Docker]):::build + end + + subgraph CD["CD — On Merge"] + Push{{Push Image
to Registry}}:::push --> Deploy_Dev([Deploy to Dev]):::dev + Push --> Deploy_Prod([Deploy to Prod]):::prod + end + + Build --> Push + + classDef lint fill:#f59e0b,stroke:#b45309,color:#fff + classDef test fill:#3b82f6,stroke:#1e40af,color:#fff + classDef build fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef push fill:#06b6d4,stroke:#0e7490,color:#fff + classDef dev fill:#22c55e,stroke:#15803d,color:#fff + classDef prod fill:#e11d48,stroke:#9f1239,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_dark.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_dark.png new file mode 100644 index 00000000..831a0f6f Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_light.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_light.png new file mode 100644 index 00000000..7e4405de Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_cicd_pipeline_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.md b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.md new file mode 100644 index 00000000..c1a6df72 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.md @@ -0,0 +1,9 @@ +```mermaid +graph LR + Dev([develop branch
Dev Environment]):::dev --> Staging([staging branch
Staging Environment]):::staging + Staging --> Prod([main branch
Production]):::prod + + classDef dev fill:#22c55e,stroke:#15803d,color:#fff + classDef staging fill:#f59e0b,stroke:#b45309,color:#fff + classDef prod fill:#e11d48,stroke:#9f1239,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.png new file mode 100644 index 00000000..7cdb6d9b Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_light.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_light.png new file mode 100644 index 00000000..2b5f8365 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_environment_promotion_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform.md b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform.md new file mode 100644 index 00000000..ac60de7f --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform.md @@ -0,0 +1,15 @@ +```mermaid +graph TD + Start{New Project}:::decision --> Q1{Enterprise client?
Complex scaling needs?}:::decision + Q1 -->|Yes| GCP([Google Cloud Platform]):::gcp + Q1 -->|No| Q2{Tight budget?
Simple infrastructure?}:::decision + Q2 -->|Yes| DO([Digital Ocean]):::do + Q2 -->|No| Q3{Client preference?}:::decision + Q3 -->|GCP| GCP + Q3 -->|DO| DO + Q3 -->|No preference| DO_Default([Digital Ocean
Simpler default]):::do + + classDef decision fill:#f59e0b,stroke:#b45309,color:#fff + classDef gcp fill:#4285f4,stroke:#1a73e8,color:#fff + classDef do fill:#0080ff,stroke:#0060cc,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_dark.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_dark.png new file mode 100644 index 00000000..5c49500c Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_light.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_light.png new file mode 100644 index 00000000..83e66c37 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_hosting_platform_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview.md b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview.md new file mode 100644 index 00000000..b588479e --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview.md @@ -0,0 +1,68 @@ +```mermaid +graph TB + subgraph Dev["Developer"] + Code([Code + Push]):::dev + end + + subgraph GH["GitHub"] + Repo{{Repository}}:::github + Actions{{GitHub Actions
CI/CD}}:::github + Registry[(Container Registry)]:::github + end + + subgraph Cloud["Cloud Platform — GCP / Digital Ocean"] + LB[[Load Balancer
SSL Termination]]:::infra + + subgraph Compute["Compute"] + API_Dev([API — Dev]):::compute_dev + API_Prod([API — Prod]):::compute_prod + end + + subgraph Data["Data"] + DB_Dev[(DB — Dev)]:::data_dev + DB_Prod[(DB — Prod)]:::data_prod + Cache_Dev[(Redis — Dev)]:::data_dev + Cache_Prod[(Redis — Prod)]:::data_prod + end + + subgraph Storage["Storage"] + Secrets[/Secret Manager/]:::storage + Files[/Cloud Storage / Spaces/]:::storage + end + end + + subgraph Mon["Monitoring"] + Sentry([Sentry]):::monitoring + Logs([Cloud Logging]):::monitoring + end + + Code --> Repo + Repo --> Actions + Actions -->|Build & Push| Registry + Actions -->|Deploy| API_Dev + Actions -->|Deploy| API_Prod + LB --> API_Dev + LB --> API_Prod + API_Dev --> DB_Dev + API_Dev --> Cache_Dev + API_Prod --> DB_Prod + API_Prod --> Cache_Prod + API_Dev --> Secrets + API_Prod --> Secrets + API_Dev --> Files + API_Prod --> Files + API_Dev --> Sentry + API_Prod --> Sentry + API_Dev --> Logs + API_Prod --> Logs + + classDef dev fill:#64748b,stroke:#334155,color:#fff + classDef github fill:#24292e,stroke:#1b1f23,color:#fff + classDef infra fill:#f59e0b,stroke:#b45309,color:#fff + classDef compute_dev fill:#22c55e,stroke:#15803d,color:#fff + classDef compute_prod fill:#e11d48,stroke:#9f1239,color:#fff + classDef data_dev fill:#059669,stroke:#065f46,color:#fff + classDef data_prod fill:#dc2626,stroke:#991b1b,color:#fff + classDef storage fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef monitoring fill:#06b6d4,stroke:#0e7490,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_dark.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_dark.png new file mode 100644 index 00000000..7869e52f Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_light.png b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_light.png new file mode 100644 index 00000000..bc42c54d Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/30_devops_infrastructure_overview_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch.md b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch.md new file mode 100644 index 00000000..bb21d558 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch.md @@ -0,0 +1,56 @@ +```mermaid +graph TB + subgraph App["Our Application"] + API([NestJS API]):::app + IntLayer{{Integration Layer
Dedicated Modules}}:::integration + end + + subgraph Auth["Authentication"] + Firebase([Firebase Auth]):::auth + Google([Google OAuth]):::auth + Apple([Apple Sign-In]):::auth + end + + subgraph Comms["Communication"] + Email([Email Service
Resend / OneSignal]):::comms + FCM([Firebase Cloud Messaging
Push Notifications]):::comms + Slack([Slack API
Alerts & Notifications]):::comms + end + + subgraph Store["Storage & Data"] + CloudStorage[(Cloud Storage
GCS / Spaces / S3)]:::storage + DB[(Database)]:::storage + end + + subgraph Pay["Payments"] + Stripe([Stripe]):::payments + GoPay([GoPay]):::payments + end + + subgraph Mon["Monitoring"] + Sentry([Sentry
Error Tracking]):::monitoring + Analytics([Google Analytics]):::monitoring + end + + API --> IntLayer + IntLayer --> Firebase + IntLayer --> Google + IntLayer --> Apple + IntLayer --> Email + IntLayer --> FCM + IntLayer --> Slack + IntLayer --> CloudStorage + IntLayer --> Stripe + IntLayer --> GoPay + API --> Sentry + API --> Analytics + API --> DB + + classDef app fill:#3b82f6,stroke:#1e40af,color:#fff + classDef integration fill:#8b5cf6,stroke:#5b21b6,color:#fff + classDef auth fill:#f59e0b,stroke:#b45309,color:#fff + classDef comms fill:#06b6d4,stroke:#0e7490,color:#fff + classDef storage fill:#059669,stroke:#065f46,color:#fff + classDef payments fill:#e11d48,stroke:#9f1239,color:#fff + classDef monitoring fill:#22c55e,stroke:#15803d,color:#fff +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_dark.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_dark.png new file mode 100644 index 00000000..1a38671a Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_light.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_light.png new file mode 100644 index 00000000..9c38c1fa Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_arch_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow.md b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow.md new file mode 100644 index 00000000..3df337aa --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow.md @@ -0,0 +1,17 @@ +```mermaid +sequenceDiagram + participant App as Application Code + participant Module as Integration Module + participant Provider as External Provider + + App->>Module: emailService.sendWelcome(user) + activate Module + Module->>Module: Build template, validate data + Module->>Provider: POST /api/send (API call) + activate Provider + Provider-->>Module: 200 OK / Error + deactivate Provider + Module->>Module: Log result, handle errors + Module-->>App: Success / throw exception + deactivate Module +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_dark.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_dark.png new file mode 100644 index 00000000..73b1ef1f Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_light.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_light.png new file mode 100644 index 00000000..e588e5af Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_flow_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment.md b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment.md new file mode 100644 index 00000000..c89854a9 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment.md @@ -0,0 +1,27 @@ +```mermaid +sequenceDiagram + participant Client as Frontend + participant API as Our API + participant Stripe as Stripe + + Client->>API: Create payment intent + activate API + API->>Stripe: POST /payment_intents + activate Stripe + Stripe-->>API: Payment intent + client_secret + deactivate Stripe + API-->>Client: client_secret + deactivate API + + Client->>Stripe: Confirm payment (card details) + activate Stripe + Stripe-->>Client: Payment result + deactivate Stripe + + Note over Stripe,API: Asynchronous webhook callback + Stripe->>API: Webhook: payment_intent.succeeded + activate API + API->>API: Verify signature, update order + API-->>Stripe: 200 OK + deactivate API +``` \ No newline at end of file diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_dark.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_dark.png new file mode 100644 index 00000000..ddcbfa66 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_dark.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_light.png b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_light.png new file mode 100644 index 00000000..b4ebd0a5 Binary files /dev/null and b/docs/teams/fullstack/tech_stack/Resources/40_integrations_stripe_payment_light.png differ diff --git a/docs/teams/fullstack/tech_stack/Resources/all_diagrams.excalidraw b/docs/teams/fullstack/tech_stack/Resources/all_diagrams.excalidraw new file mode 100644 index 00000000..6b008fb9 --- /dev/null +++ b/docs/teams/fullstack/tech_stack/Resources/all_diagrams.excalidraw @@ -0,0 +1,26760 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "text", + "version": 1129, + "versionNonce": 1004760743, + "index": "Zx", + "isDeleted": false, + "id": "K-pdxduw3ewoENGcQZnbH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1940, + "y": 720, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 138.29193115234375, + "height": 37.800000000000004, + "seed": 147430910, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Nuxt Layer", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Nuxt Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1416, + "versionNonce": 1002590498, + "index": "Zy", + "isDeleted": true, + "id": "wqNaTXwWuQSN6hmaQARyc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1813.9164024819759, + "y": 786.6277599622343, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 241.7400448404612, + "height": 331.09793060089595, + "seed": 1858072236, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + }, + { + "id": "n4sCZ1A-o33GfmA14LPeH", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 766, + "versionNonce": 354437630, + "index": "aF", + "isDeleted": true, + "id": "2h3Uie7pzH4M1ozRHYX43", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1858.0319115163684, + "y": 1025.1874370402843, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 157.265625, + "height": 61.42909850744659, + "seed": 2138108332, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "oKyTZwkUyuTY8eue0j5us" + }, + { + "id": "n4sCZ1A-o33GfmA14LPeH", + "type": "arrow" + }, + { + "id": "mQAxMrj0ISpfEW3Tg5Sl9", + "type": "arrow" + }, + { + "id": "Bw7waxDDVnWwsPMiYkL47", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 669, + "versionNonce": 56614114, + "index": "aG", + "isDeleted": true, + "id": "oKyTZwkUyuTY8eue0j5us", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1884.2247597219348, + "y": 1042.4019862940077, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 104.87992858886719, + "height": 27, + "seed": 199469460, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Component", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "2h3Uie7pzH4M1ozRHYX43", + "originalText": "Component", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1375, + "versionNonce": 1220696638, + "index": "aH", + "isDeleted": true, + "id": "rFwfqNOMmR0HY0Soy798E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1855.9293285672036, + "y": 873.1373675427988, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 157.265625, + "height": 50.16796875000001, + "seed": 975595924, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "57cZjfR85zYAFC-tfPTfd" + }, + { + "id": "L2g9efcTF38LIO7RUsZy2", + "type": "arrow" + }, + { + "id": "Bw7waxDDVnWwsPMiYkL47", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1330, + "versionNonce": 1591079074, + "index": "aI", + "isDeleted": true, + "id": "57cZjfR85zYAFC-tfPTfd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1910.632171279606, + "y": 884.7213519177988, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 47.85993957519531, + "height": 27, + "seed": 642520852, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "State", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "rFwfqNOMmR0HY0Soy798E", + "originalText": "State", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2346, + "versionNonce": 372793982, + "index": "aJ", + "isDeleted": true, + "id": "Bw7waxDDVnWwsPMiYkL47", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1943.2756545395346, + "y": 1024.5227269077823, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 2.740067253922689, + "height": 100.90611079294729, + "seed": 821083668, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "IX1vm1WDkJ8P32mCWJZYI" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2h3Uie7pzH4M1ozRHYX43", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "endBinding": { + "elementId": "rFwfqNOMmR0HY0Soy798E", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 2.6271480773593794, + -43.20187592431603 + ], + [ + 2.740067253922689, + -100.90611079294729 + ] + ], + "elbowed": false + }, + { + "type": "text", + "version": 70, + "versionNonce": 1372818530, + "index": "aK", + "isDeleted": true, + "id": "IX1vm1WDkJ8P32mCWJZYI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1194.0883698758707, + "y": 1051.761292206449, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 91.53593444824219, + "height": 21.6, + "seed": 1532495404, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "mutate state", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Bw7waxDDVnWwsPMiYkL47", + "originalText": "mutate state", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1029, + "versionNonce": 272851646, + "index": "aY", + "isDeleted": true, + "id": "oycsE3qKwLwOE9auYTP71", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2106.861547984022, + "y": 1026.877807939934, + "strokeColor": "#ffffff", + "backgroundColor": "#fc1d32", + "width": 157.265625, + "height": 61.42909850744659, + "seed": 727051156, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "pYM_DF_WvhhWeHyN803pC" + }, + { + "id": "mQAxMrj0ISpfEW3Tg5Sl9", + "type": "arrow" + }, + { + "id": "qY9kBZz91jNk0TLCIRzHi", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 952, + "versionNonce": 304590882, + "index": "aZ", + "isDeleted": true, + "id": "pYM_DF_WvhhWeHyN803pC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2145.534383572477, + "y": 1044.0923571936573, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 79.9199538230896, + "height": 27, + "seed": 171661588, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "UseCase", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "oycsE3qKwLwOE9auYTP71", + "originalText": "UseCase", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 673, + "versionNonce": 1233410814, + "index": "ag", + "isDeleted": true, + "id": "mQAxMrj0ISpfEW3Tg5Sl9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2021.7356258707603, + "y": 1058.0310162873843, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 76.91023457942583, + "height": 0.7514990170350302, + "seed": 1524908204, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2h3Uie7pzH4M1ozRHYX43", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "oycsE3qKwLwOE9auYTP71", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 76.91023457942583, + 0.7514990170350302 + ] + ], + "elbowed": false + }, + { + "type": "text", + "version": 1929, + "versionNonce": 1136745442, + "index": "ak", + "isDeleted": true, + "id": "E4V-1ldcv1yzOkEmjjuwd", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2360.8662179089, + "y": 1125.5149286661872, + "strokeColor": "#8a84d6", + "backgroundColor": "transparent", + "width": 99.93989872932434, + "height": 27, + "seed": 1640849580, + "groupIds": [ + "YuPMMiYKCgWOlccGIiQcb" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Data Layer", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Data Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 2403, + "versionNonce": 1484540734, + "index": "al", + "isDeleted": true, + "id": "6nlh-iaz3C_XetlaRzdl8", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2365.818354662015, + "y": 1157.5856854382655, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 91.94422912597656, + "height": 32.881111928735194, + "seed": 1362389804, + "groupIds": [ + "YuPMMiYKCgWOlccGIiQcb" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 12.178189603235257, + "fontFamily": 6, + "text": "Observable\nCoroutine-based", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Observable\nCoroutine-based", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1722, + "versionNonce": 1833021090, + "index": "ao", + "isDeleted": true, + "id": "Y-gzJKC3MTT8fmI38zV4G", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2323.832991041939, + "y": 1026.2241766200618, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 157.265625, + "height": 61.42909850744659, + "seed": 1745642412, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "VaEPJLJQFtQbKmR4wOR3m" + }, + { + "id": "qY9kBZz91jNk0TLCIRzHi", + "type": "arrow" + }, + { + "id": "13TxWvPmOVlucN3uf4AON", + "type": "arrow" + }, + { + "id": "zMjQ6YnsCj2Ydvai4IcQF", + "type": "arrow" + }, + { + "id": "ojjwDSOJl0WknhAxH-Na0", + "type": "arrow" + }, + { + "id": "bI3fXJ2MP9OEoGLkEfAVt", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1638, + "versionNonce": 1139770494, + "index": "ap", + "isDeleted": true, + "id": "VaEPJLJQFtQbKmR4wOR3m", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2353.595846571724, + "y": 1043.4387258737852, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 97.73991394042969, + "height": 27, + "seed": 1587220012, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Repository", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Y-gzJKC3MTT8fmI38zV4G", + "originalText": "Repository", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 1376, + "versionNonce": 1477937762, + "index": "aq", + "isDeleted": true, + "id": "qY9kBZz91jNk0TLCIRzHi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2265.2365932304847, + "y": 1056.058643504669, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 57.06362139971657, + "height": 0.20804935660930823, + "seed": 503116564, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": { + "elementId": "oycsE3qKwLwOE9auYTP71", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "Y-gzJKC3MTT8fmI38zV4G", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 57.06362139971657, + 0.20804935660930823 + ] + ], + "elbowed": false + }, + { + "type": "rectangle", + "version": 1802, + "versionNonce": 1767570686, + "index": "at", + "isDeleted": true, + "id": "WFAhJTm9LZxKfDg6c4mnt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2437.058775255092, + "y": 859.9875929609848, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 219.54722395925887, + "height": 37, + "seed": 456014996, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "CDpcDCS4K3mkRVgO4VgrU" + }, + { + "id": "ojjwDSOJl0WknhAxH-Na0", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1795, + "versionNonce": 731765218, + "index": "au", + "isDeleted": true, + "id": "CDpcDCS4K3mkRVgO4VgrU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2442.058775255092, + "y": 867.6875929609848, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 77.56791687011719, + "height": 21.6, + "seed": 1558284820, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "ApiService", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "WFAhJTm9LZxKfDg6c4mnt", + "originalText": "ApiService", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1849, + "versionNonce": 195188094, + "index": "av", + "isDeleted": true, + "id": "x9b_hGTOXf8dCA6kR_Vaw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2437.058775255092, + "y": 908.6416049509878, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 219.54722395925887, + "height": 37, + "seed": 655576492, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "-DD8MldnOuEbQtwkjOVxt" + }, + { + "id": "zMjQ6YnsCj2Ydvai4IcQF", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1912, + "versionNonce": 913721698, + "index": "aw", + "isDeleted": true, + "id": "-DD8MldnOuEbQtwkjOVxt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2442.058775255092, + "y": 916.3416049509879, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 82.46391296386719, + "height": 21.6, + "seed": 825538604, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Persistence", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "x9b_hGTOXf8dCA6kR_Vaw", + "originalText": "Persistence", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1891, + "versionNonce": 1296928254, + "index": "ax", + "isDeleted": true, + "id": "qmwYiFFWddoEqkMUROLyX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2437.058775255092, + "y": 957.2956169409907, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 219.54722395925887, + "height": 37, + "seed": 1205673108, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "wbSQJrkhSK4ioThK-EcT2" + }, + { + "id": "13TxWvPmOVlucN3uf4AON", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1960, + "versionNonce": 580442338, + "index": "ay", + "isDeleted": true, + "id": "wbSQJrkhSK4ioThK-EcT2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2442.058775255092, + "y": 964.995616940991, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 111.19993591308594, + "height": 21.6, + "seed": 1354000916, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "RoomDatabase", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "qmwYiFFWddoEqkMUROLyX", + "originalText": "RoomDatabase", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1849, + "versionNonce": 1323607678, + "index": "az", + "isDeleted": true, + "id": "D9hwifI55ulrFp7GGEnZt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2437.058775255092, + "y": 811.3335809709818, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 219.54722395925887, + "height": 37, + "seed": 394886420, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "J_Yq928PKFbm5Gc9nuGhk" + }, + { + "id": "bI3fXJ2MP9OEoGLkEfAVt", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1856, + "versionNonce": 2080213090, + "index": "b00", + "isDeleted": true, + "id": "J_Yq928PKFbm5Gc9nuGhk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2442.058775255092, + "y": 816.3335809709818, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 13.979965209960938, + "height": 27, + "seed": 486587028, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "...", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "D9hwifI55ulrFp7GGEnZt", + "originalText": "...", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2018, + "versionNonce": 1925654206, + "index": "b01", + "isDeleted": true, + "id": "13TxWvPmOVlucN3uf4AON", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2392.824689151961, + "y": 1021.2241766200617, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 39.23408610313095, + "height": 45.528559679070895, + "seed": 120356780, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -45.528559679070895 + ], + [ + 39.23408610313095, + -45.528559679070895 + ] + ], + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 2142, + "versionNonce": 1571957794, + "index": "b02", + "isDeleted": true, + "id": "zMjQ6YnsCj2Ydvai4IcQF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2392.170197684214, + "y": 1021.2241766200617, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 39.88857757087794, + "height": 94.18257166907392, + "seed": 1351300140, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -94.18257166907392 + ], + [ + 39.88857757087794, + -94.18257166907392 + ] + ], + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 2217, + "versionNonce": 787455742, + "index": "b03", + "isDeleted": true, + "id": "ojjwDSOJl0WknhAxH-Na0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2391.7588113156644, + "y": 1021.2241766200617, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40.29996393942747, + "height": 142.83658365907695, + "seed": 1672246316, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -142.83658365907695 + ], + [ + 40.29996393942747, + -142.83658365907695 + ] + ], + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 2319, + "versionNonce": 815552482, + "index": "b04", + "isDeleted": true, + "id": "bI3fXJ2MP9OEoGLkEfAVt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2391.7845048767495, + "y": 1021.2241766200617, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40.27427037834286, + "height": 191.49059564907998, + "seed": 217660460, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -191.49059564907998 + ], + [ + 40.27427037834286, + -191.49059564907998 + ] + ], + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "text", + "version": 1019, + "versionNonce": 2011107134, + "index": "b05", + "isDeleted": true, + "id": "H_WYUbmqA5JR8Cnl3kXAQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1828.372279107689, + "y": 802.7327963028662, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 219.5198974609375, + "height": 37.800000000000004, + "seed": 1721230252, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Screen / NavHost", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Screen / NavHost", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1639, + "versionNonce": 1154157474, + "index": "b09", + "isDeleted": true, + "id": "wwHBumYE5-DbWCbrO_VmN", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1459.9018828592914, + "y": 1130.5149286661872, + "strokeColor": "#17c4b7", + "backgroundColor": "transparent", + "width": 101.71991515159607, + "height": 27, + "seed": 1835779372, + "groupIds": [ + "nGsv_2cW3Z04d2La4FVNN" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "L2g9efcTF38LIO7RUsZy2", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "View Layer", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "View Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 2048, + "versionNonce": 167147390, + "index": "b0A", + "isDeleted": true, + "id": "OSxeXwTA9yIr9rcjT9NfX", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1486.3113038245185, + "y": 1162.5856854382655, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 50.80967712402344, + "height": 16.440555964367597, + "seed": 1264075668, + "groupIds": [ + "nGsv_2cW3Z04d2La4FVNN" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 12.178189603235257, + "fontFamily": 6, + "text": "Native UI", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Native UI", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1140, + "versionNonce": 275597154, + "index": "b0B", + "isDeleted": true, + "id": "kImSOq9NhXV28PFCqklSa", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1855.4673519103158, + "y": 1125.5149286661872, + "strokeColor": "#ff5f00", + "backgroundColor": "transparent", + "width": 171.19983220100403, + "height": 27, + "seed": 273176084, + "groupIds": [ + "jQdzQgXKY3gbjdgCs8Eyt" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Presentation Layer", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Presentation Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1581, + "versionNonce": 1836505022, + "index": "b0C", + "isDeleted": true, + "id": "QUhwqbWtzxkVPviUP_AO5", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1898.544297928567, + "y": 1157.5856854382655, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 86.95454406738281, + "height": 32.881111928735194, + "seed": 712799124, + "groupIds": [ + "jQdzQgXKY3gbjdgCs8Eyt" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 12.178189603235257, + "fontFamily": 6, + "text": "Lifecycle-aware\nDecompose", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Lifecycle-aware\nDecompose", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1128, + "versionNonce": 1808927522, + "index": "b0D", + "isDeleted": true, + "id": "q4pil77MoKNMaDabjC7Ul", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2122.3068081493393, + "y": 1125.5149286661872, + "strokeColor": "#fc1d32", + "backgroundColor": "transparent", + "width": 126.71988224983215, + "height": 27, + "seed": 90137108, + "groupIds": [ + "1n4FbHuUM-SQ3Yogxb7pC" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Domain Layer", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Domain Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1577, + "versionNonce": 2055286782, + "index": "b0E", + "isDeleted": true, + "id": "SpJjjnkMyalhwfoTccSHU", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2140.6489366627084, + "y": 1157.5856854382655, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 91.94422912597656, + "height": 32.881111928735194, + "seed": 13762452, + "groupIds": [ + "1n4FbHuUM-SQ3Yogxb7pC" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 12.178189603235257, + "fontFamily": 6, + "text": "Business logic\nCoroutine-based", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Business logic\nCoroutine-based", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1803, + "versionNonce": 1298683618, + "index": "b0F", + "isDeleted": true, + "id": "hza_gn96nHmm7t3gOk4rT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1789.1198536603194, + "y": 700, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 886.8454297115055, + "height": 509.1297868646861, + "seed": 1221434736, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2022, + "versionNonce": 1561755710, + "index": "b0P", + "isDeleted": true, + "id": "Jz7lJKKYOb9gEJC5VVb03", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1383.9417160015928, + "y": 787.3221370914277, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 254.79863876064414, + "height": 140.85230902430277, + "seed": 2040275344, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 1921, + "versionNonce": 96414370, + "index": "b0U", + "isDeleted": true, + "id": "NHyp-7vLVy6D-PLRCd_0J", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1360, + "y": 703.0347859813143, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 301.52368087017885, + "height": 509.297361887655, + "seed": 426569104, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "L2g9efcTF38LIO7RUsZy2", + "type": "arrow" + }, + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + }, + { + "id": "n4sCZ1A-o33GfmA14LPeH", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 945, + "versionNonce": 420989054, + "index": "b0V", + "isDeleted": true, + "id": "Ptb9A5hBSdwpHzWN9Y8mQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1455.573875042023, + "y": 720.9687637258935, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 110.37593078613281, + "height": 37.800000000000004, + "seed": 555581808, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Platform", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Platform", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2426, + "versionNonce": 2072348258, + "index": "b0W", + "isDeleted": true, + "id": "L2g9efcTF38LIO7RUsZy2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1849.9293285672036, + "y": 898.3868973406627, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 182.40564769702462, + "height": 4.880221332901328, + "seed": 244096172, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "0mqOuGPY4bVr1Ca1whlZL" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": { + "elementId": "rFwfqNOMmR0HY0Soy798E", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "endBinding": { + "elementId": "NHyp-7vLVy6D-PLRCd_0J", + "mode": "orbit", + "fixedPoint": [ + 0.6001979222937874, + 0.39980207770621207 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -182.40564769702462, + 4.880221332901328 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 33, + "versionNonce": 239470782, + "index": "b0X", + "isDeleted": true, + "id": "0mqOuGPY4bVr1Ca1whlZL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 954.8105273417762, + "y": 972.8130700665462, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 97.919921875, + "height": 21.6, + "seed": 617664684, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "observe state", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "L2g9efcTF38LIO7RUsZy2", + "originalText": "observe state", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 1923, + "versionNonce": 1737124386, + "index": "b0a", + "isDeleted": true, + "id": "n4sCZ1A-o33GfmA14LPeH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1853.9902138199743, + "y": 1071.1091659306485, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 189.4863536995839, + "height": 5.043084393713798, + "seed": 1855785516, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "w-G2bcJOhc89YlWiZOG2E" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2h3Uie7pzH4M1ozRHYX43", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "endBinding": { + "elementId": "VUJ3mhrIdNcCK2CWgyoaG", + "mode": "orbit", + "fixedPoint": [ + 0.8126316534216393, + 0.81263165342164 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -189.4863536995839, + -5.043084393713798 + ] + ], + "elbowed": false + }, + { + "type": "text", + "version": 47, + "versionNonce": 2084716798, + "index": "b0b", + "isDeleted": true, + "id": "w-G2bcJOhc89YlWiZOG2E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 942.6220145095839, + "y": 1119.840266914803, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 120.95986938476562, + "height": 21.6, + "seed": 355803180, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "(one-shot event)", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "n4sCZ1A-o33GfmA14LPeH", + "originalText": "(one-shot event)", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2125, + "versionNonce": 280810978, + "index": "b0c", + "isDeleted": true, + "id": "VUJ3mhrIdNcCK2CWgyoaG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1383.3625210547675, + "y": 961.7918469745251, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 254.79863876064414, + "height": 131.71912870655171, + "seed": 1561017200, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + }, + { + "id": "n4sCZ1A-o33GfmA14LPeH", + "type": "arrow" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2911, + "versionNonce": 109932862, + "index": "b0gV", + "isDeleted": true, + "id": "D1oYicuaQPRPr4OEK9VqF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1404.4036898242475, + "y": 858.8775974991325, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 213.18689711597972, + "height": 52.57441409147705, + "seed": 1980562832, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "FSJHW1Y4UIGjRjnKhv_N9" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 2920, + "versionNonce": 137087394, + "index": "b0h", + "isDeleted": true, + "id": "FSJHW1Y4UIGjRjnKhv_N9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1456.2071756136825, + "y": 871.6648045448711, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 109.57992553710938, + "height": 27, + "seed": 615959440, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Compose UI", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "D1oYicuaQPRPr4OEK9VqF", + "originalText": "Compose UI", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1699, + "versionNonce": 948476286, + "index": "b0hG", + "isDeleted": true, + "id": "v0_q4-oaNvWjVAH_jiUg4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1484.5735256529151, + "y": 802.7105476750327, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 101.025146484375, + "height": 37.54329685914128, + "seed": 851537808, + "groupIds": [ + "XyTNwc0_IPDaoaXXrKndl" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 27.809849525289835, + "fontFamily": 6, + "text": "Android", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Android", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "enLU0NafAbKM5TpYu9uAp", + "type": "image", + "x": 1435.9250087328887, + "y": 796.0439206813343, + "width": 45.37648432400857, + "height": 49.07624563579825, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "XyTNwc0_IPDaoaXXrKndl" + ], + "frameId": null, + "index": "b0hV", + "roundness": null, + "seed": 1479677328, + "version": 704, + "versionNonce": 1694909794, + "isDeleted": true, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "status": "saved", + "fileId": "705d1dc22dc2df1d2ff8e3d56c6efba2bf6515e9", + "scale": [ + 1, + 1 + ], + "crop": null + }, + { + "type": "text", + "version": 1732, + "versionNonce": 158644670, + "index": "b0jV", + "isDeleted": true, + "id": "19Eeccbj9DeSq1hdrIeTh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1514.0856613217773, + "y": 971.819907946793, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 45.20277404785156, + "height": 37.54329685914128, + "seed": 1894927728, + "groupIds": [ + "X_B4Ez7MuPAuYgr7O9yQ9" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 27.809849525289835, + "fontFamily": 6, + "text": "iOS", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "iOS", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "IjrT0LrW3_xzILZQDjy95", + "type": "image", + "x": 1461.7574096694188, + "y": 966.9412204491294, + "width": 46.37188363993956, + "height": 44.705893237870434, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "X_B4Ez7MuPAuYgr7O9yQ9" + ], + "frameId": null, + "index": "b0k", + "roundness": null, + "seed": 2071714704, + "version": 493, + "versionNonce": 10176802, + "isDeleted": true, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "status": "saved", + "fileId": "6289780f369aa61d4ea7cf622297bed0d4598c6e", + "scale": [ + 1, + 1 + ], + "crop": null + }, + { + "type": "text", + "version": 843, + "versionNonce": 1618137598, + "index": "b0l", + "isDeleted": true, + "id": "RRBtKeNrfAERC4_RdW0mN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2122.6673887714987, + "y": 717.7739797353404, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 255.44381713867188, + "height": 37.800000000000004, + "seed": 1829491600, + "groupIds": [ + "6NkoKgYMTf6k8bA1BsBfq" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Kotlin Multiplatform", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Kotlin Multiplatform", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "yb6WQMbv9Syc3F6ocoMAX", + "type": "image", + "x": 2086.0286186219737, + "y": 720.824880082193, + "width": 28.055266580927544, + "height": 30.34981521364433, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "6NkoKgYMTf6k8bA1BsBfq" + ], + "frameId": null, + "index": "b0m", + "roundness": null, + "seed": 1843288432, + "version": 392, + "versionNonce": 844748002, + "isDeleted": true, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "status": "saved", + "fileId": "cbbe97051e830a30d27917630d4549d3547111ff", + "scale": [ + 1, + 1 + ], + "crop": null + }, + { + "type": "rectangle", + "version": 2966, + "versionNonce": 411296318, + "index": "b0n", + "isDeleted": true, + "id": "afAzgGWhvSL_6liTviZr-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1407.0442205419456, + "y": 1024.204576864145, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 213.18689711597972, + "height": 52.57441409147705, + "seed": 1809592720, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "IUh53H2UF2z-6q-UTHdvA" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 2983, + "versionNonce": 198240418, + "index": "b0o", + "isDeleted": true, + "id": "IUh53H2UF2z-6q-UTHdvA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1480.0577054158534, + "y": 1036.9917839098835, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 67.15992736816406, + "height": 27, + "seed": 41910160, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "SwiftUI", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "afAzgGWhvSL_6liTviZr-", + "originalText": "SwiftUI", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2036, + "versionNonce": 585957831, + "index": "b0p", + "isDeleted": false, + "id": "cpYT2-yaChbOwTx6DpO3e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2660, + "y": 720, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 500, + "height": 460.0000000000001, + "seed": 1207046398, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2204, + "versionNonce": 362229991, + "index": "b0r", + "isDeleted": false, + "id": "nsVK4cs2HM_bx7cbBnIPQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2660, + "y": 1220, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1040, + "height": 140, + "seed": 489012414, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1139, + "versionNonce": 225344519, + "index": "b0t", + "isDeleted": false, + "id": "3TYmeaDgvO_e6urB_a57F", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2460, + "y": 720, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 106.53993225097656, + "height": 37.800000000000004, + "seed": 561654626, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Browser", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Browser", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1227, + "versionNonce": 510616359, + "index": "b0u", + "isDeleted": false, + "id": "fXKmSIE3NdAUj9Gp5f3QK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1760, + "y": 1250, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 112.97993469238281, + "height": 75.60000000000001, + "seed": 838813438, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "External \nServices", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "External \nServices", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1886, + "versionNonce": 2089650215, + "index": "b13", + "isDeleted": false, + "id": "yI1dv38inyXae-rCzLZ84", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2060, + "y": 1240, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 217.265625, + "height": 100.00000000000001, + "seed": 779945342, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Lg6l-P0WZWOPp4tlZpMqz" + }, + { + "id": "kPLMsg-RaliXKURi5OIGS", + "type": "arrow" + }, + { + "id": "xp5it2Nn_WADNo0a81V51", + "type": "arrow" + } + ], + "updated": 1774014713771, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1810, + "versionNonce": 224349513, + "index": "b14", + "isDeleted": false, + "id": "Lg6l-P0WZWOPp4tlZpMqz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2025.0771102905273, + "y": 1263, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 147.4198455810547, + "height": 54, + "seed": 503031230, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774012787904, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Backend API\nREST / GraphQL", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yI1dv38inyXae-rCzLZ84", + "originalText": "Backend API\nREST / GraphQL", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1907, + "versionNonce": 383303815, + "index": "b15", + "isDeleted": false, + "id": "DIW_5y3At3AC_jFTZsTtq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2360, + "y": 1240, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 217.27, + "height": 100.00000000000001, + "seed": 2063820606, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ebmxGbzKOSaAKpvH9t01q" + }, + { + "id": "PXmySXcx7UP_RaaosnNEH", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1859, + "versionNonce": 2065504167, + "index": "b16", + "isDeleted": false, + "id": "ebmxGbzKOSaAKpvH9t01q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2314.114931335449, + "y": 1263, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 125.49986267089844, + "height": 54, + "seed": 1456459646, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Auth Provider\nOAuth / JWT", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "DIW_5y3At3AC_jFTZsTtq", + "originalText": "Auth Provider\nOAuth / JWT", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1871, + "versionNonce": 2131331783, + "index": "b17", + "isDeleted": false, + "id": "3Spp8mrcZg9MXepQ5drJ3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 1240, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 217.27, + "height": 100.00000000000001, + "seed": 985947582, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "c2PBQ1Ay9qW0RM3OI7A9_" + }, + { + "id": "fB4icsfKClx9S5dbhDId4", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1860, + "versionNonce": 792369639, + "index": "b18", + "isDeleted": false, + "id": "c2PBQ1Ay9qW0RM3OI7A9_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2548.444925537109, + "y": 1263, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 114.15985107421875, + "height": 54, + "seed": 271447550, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "CDN\nStatic assets", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "3Spp8mrcZg9MXepQ5drJ3", + "originalText": "CDN\nStatic assets", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1158, + "versionNonce": 1354548487, + "index": "b1D", + "isDeleted": false, + "id": "bCFj-2psC1jO3ofEPISdO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2320, + "y": 1060, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 140, + "height": 80, + "seed": 421256894, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "wN2C5W9UVwSWQ5WZt1xcQ" + }, + { + "id": "Ygnw-iaOoqppjkCrjH6gl", + "type": "arrow" + }, + { + "id": "QWCS1GyzOCBXXYXqVNDpb", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1097, + "versionNonce": 1393331239, + "index": "b1E", + "isDeleted": false, + "id": "wN2C5W9UVwSWQ5WZt1xcQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2311.2399520874023, + "y": 1086.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 122.47990417480469, + "height": 27, + "seed": 434984702, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Composables", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bCFj-2psC1jO3ofEPISdO", + "originalText": "Composables", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1207, + "versionNonce": 35024711, + "index": "b1F", + "isDeleted": false, + "id": "Rshmi9xEWpAp-k9_tQ5AL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 1060, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 140, + "height": 80, + "seed": 730414078, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "cSYo16WEWInwC_rQ9TsVG" + }, + { + "id": "Ux5vG0eabsqv3OAl8vGxQ", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1148, + "versionNonce": 2016865895, + "index": "b1G", + "isDeleted": false, + "id": "cSYo16WEWInwC_rQ9TsVG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2583.799934387207, + "y": 1086.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 107.59986877441406, + "height": 27, + "seed": 1228737598, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Pinia Stores", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Rshmi9xEWpAp-k9_tQ5AL", + "originalText": "Pinia Stores", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 983, + "versionNonce": 1346013575, + "index": "b1H", + "isDeleted": false, + "id": "KKUbgOkCFor0VIvWWy-dJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 760, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 380, + "height": 80, + "seed": 1495271870, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "KFca4TNshe4yudfCU09iT" + }, + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 920, + "versionNonce": 392020135, + "index": "b1I", + "isDeleted": false, + "id": "KFca4TNshe4yudfCU09iT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2464.9299392700195, + "y": 786.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 109.85987854003906, + "height": 27, + "seed": 1043603966, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Nuxt Router", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KKUbgOkCFor0VIvWWy-dJ", + "originalText": "Nuxt Router", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2082, + "versionNonce": 994389543, + "index": "b1M", + "isDeleted": false, + "id": "rUlIg9OHKO6Cd6zAyePsb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 1560, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 900, + "height": 519.9999999999998, + "seed": 1578502654, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3143, + "versionNonce": 1065472583, + "index": "b1N", + "isDeleted": false, + "id": "WTT7g6O0x3PLUV4L11yYe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2560, + "y": 1600, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 194351751, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "7Wv5r4GRTEzCOmpbdVLLY", + "type": "arrow" + }, + { + "id": "kQ3acxYSHFX1UrYHQFnPA", + "type": "text" + } + ], + "updated": 1774009346026, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3194, + "versionNonce": 1525174055, + "index": "b1O", + "isDeleted": false, + "id": "kQ3acxYSHFX1UrYHQFnPA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2522.29988861084, + "y": 1633, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 204.5997772216797, + "height": 54, + "seed": 1385463138, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009346026, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "SSR\nServer-Side Rendering", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "WTT7g6O0x3PLUV4L11yYe", + "originalText": "SSR\nServer-Side Rendering", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3131, + "versionNonce": 1759406983, + "index": "b1P", + "isDeleted": false, + "id": "bY8JsyP2Uu1L362W7XrsJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2560, + "y": 1760, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 280, + "height": 120.00000000000001, + "seed": 1938658942, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "VBkRDFSoz134VfPDNMS90" + }, + { + "id": "Vm4cm2vFmaSIcb8roRpsN", + "type": "arrow" + } + ], + "updated": 1774001862759, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3238, + "versionNonce": 1966432935, + "index": "b1Q", + "isDeleted": false, + "id": "VBkRDFSoz134VfPDNMS90", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2528.1298751831055, + "y": 1793, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 216.25975036621094, + "height": 54, + "seed": 1959925438, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "SPA\nSingle Page Application", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bY8JsyP2Uu1L362W7XrsJ", + "originalText": "SPA\nSingle Page Application", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3162, + "versionNonce": 1172338119, + "index": "b1R", + "isDeleted": false, + "id": "1KHHCNIJ_-2KOyBKP_j_D", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2560, + "y": 1920, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 120.00000000000001, + "seed": 1985426850, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "TVCsXt1vcfb7-1o7nvC8f" + }, + { + "id": "kPdEJajN4bnXHkVgszAYI", + "type": "arrow" + } + ], + "updated": 1774001862759, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3245, + "versionNonce": 1912349927, + "index": "b1S", + "isDeleted": false, + "id": "TVCsXt1vcfb7-1o7nvC8f", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2520.6898803710938, + "y": 1953, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 201.3797607421875, + "height": 54, + "seed": 1390686562, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "SSG\nStatic Side Generation", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1KHHCNIJ_-2KOyBKP_j_D", + "originalText": "SSG\nStatic Side Generation", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1032, + "versionNonce": 2135757767, + "index": "b1T", + "isDeleted": false, + "id": "uKguRheWdRNktVZka7Cdt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 860, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 380, + "height": 80, + "seed": 2010555646, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "G1vWfs-hqcBBDdj_2AmGp" + }, + { + "id": "0zX1qYHDPewklEOFvj4QD", + "type": "arrow" + }, + { + "id": "LTmzzMoXFrWHTp5lPxsng", + "type": "arrow" + }, + { + "id": "S5dSkBXUSg76SDQt3W13H", + "type": "arrow" + }, + { + "id": "Ygnw-iaOoqppjkCrjH6gl", + "type": "arrow" + }, + { + "id": "Ux5vG0eabsqv3OAl8vGxQ", + "type": "arrow" + }, + { + "id": "fB4icsfKClx9S5dbhDId4", + "type": "arrow" + }, + { + "id": "PXmySXcx7UP_RaaosnNEH", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 955, + "versionNonce": 1344602855, + "index": "b1U", + "isDeleted": false, + "id": "G1vWfs-hqcBBDdj_2AmGp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2487.3099365234375, + "y": 886.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 154.619873046875, + "height": 27, + "seed": 1509250366, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Vue Components", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "uKguRheWdRNktVZka7Cdt", + "originalText": "Vue Components", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1025, + "versionNonce": 443682311, + "index": "b1V", + "isDeleted": false, + "id": "qvvo7HObesyo5ZT27b9sr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2060, + "y": 760, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 380, + "height": 80, + "seed": 422168382, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "cGw0e4Fl-7fK92CihBo3p" + }, + { + "id": "oMk_jAtdzpB0c7wKtyOOu", + "type": "arrow" + }, + { + "id": "LTmzzMoXFrWHTp5lPxsng", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 961, + "versionNonce": 691057959, + "index": "b1W", + "isDeleted": false, + "id": "cGw0e4Fl-7fK92CihBo3p", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1952.8499145507812, + "y": 786.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 165.6998291015625, + "height": 27, + "seed": 556412798, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Route Middleware", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "qvvo7HObesyo5ZT27b9sr", + "originalText": "Route Middleware", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1039, + "versionNonce": 869103687, + "index": "b1X", + "isDeleted": false, + "id": "psImpelHuue29n4JsmLkX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2060, + "y": 860, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 380, + "height": 80, + "seed": 1403171838, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "riYIl6Aik_XNJWQMzvy31" + }, + { + "id": "0zX1qYHDPewklEOFvj4QD", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 979, + "versionNonce": 1344591719, + "index": "b1Y", + "isDeleted": false, + "id": "riYIl6Aik_XNJWQMzvy31", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1903.8499603271484, + "y": 886.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 67.69992065429688, + "height": 27, + "seed": 526877758, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Plugins", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "psImpelHuue29n4JsmLkX", + "originalText": "Plugins", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1027, + "versionNonce": 612586119, + "index": "b1Z", + "isDeleted": false, + "id": "hkW4E8W2PBqH1elRpqblc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2060, + "y": 960, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 380, + "height": 80, + "seed": 399637822, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "mZjLu8_uL9k7zok5kKSzY" + }, + { + "id": "S5dSkBXUSg76SDQt3W13H", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 966, + "versionNonce": 1504012711, + "index": "b1a", + "isDeleted": false, + "id": "mZjLu8_uL9k7zok5kKSzY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1944.929916381836, + "y": 986.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 149.85983276367188, + "height": 27, + "seed": 1230742910, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "SSR/SPA Engine", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "hkW4E8W2PBqH1elRpqblc", + "originalText": "SSR/SPA Engine", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1023, + "versionNonce": 1287101639, + "index": "b1b", + "isDeleted": false, + "id": "ntHUF_yYTUblG1GM9xT3-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2060, + "y": 1060, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 380, + "height": 80, + "seed": 869276194, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "q8C75d1pi5sHIYHY0uVPY" + }, + { + "id": "xp5it2Nn_WADNo0a81V51", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 959, + "versionNonce": 22440935, + "index": "b1c", + "isDeleted": false, + "id": "q8C75d1pi5sHIYHY0uVPY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1986.479866027832, + "y": 1086.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 232.95973205566406, + "height": 27, + "seed": 684492258, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Server Routes / API Proxy", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ntHUF_yYTUblG1GM9xT3-", + "originalText": "Server Routes / API Proxy", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2105, + "versionNonce": 1401837319, + "index": "b1d", + "isDeleted": false, + "id": "Z-dx1SiNk9Snp5Scvxkx7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2120, + "y": 720, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 500, + "height": 460.0000000000001, + "seed": 885244286, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "S5dSkBXUSg76SDQt3W13H", + "type": "arrow" + }, + { + "id": "xp5it2Nn_WADNo0a81V51", + "type": "arrow" + } + ], + "updated": 1774001483264, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 2538, + "versionNonce": 1776016935, + "index": "b1dV", + "isDeleted": false, + "id": "oMk_jAtdzpB0c7wKtyOOu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2214, + "y": 800.0079999999998, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 148, + "height": 0.00029999999992469384, + "seed": 1795572908, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "KKUbgOkCFor0VIvWWy-dJ", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "qvvo7HObesyo5ZT27b9sr", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 148, + -0.00029999999992469384 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2044, + "versionNonce": 76081790, + "index": "b1e", + "isDeleted": true, + "id": "s2nbjTVj0j-skA04MtKYA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1615.848516147826, + "y": 1036.3770114623658, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 186.8984226877368, + "height": 2.207559979978896, + "seed": 56601726, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "XMZN4itz0bWXuCPup06IY" + } + ], + "updated": 1774259099222, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 186.8984226877368, + -2.207559979978896 + ] + ], + "elbowed": false + }, + { + "type": "text", + "version": 26, + "versionNonce": 347047010, + "index": "b1f", + "isDeleted": true, + "id": "XMZN4itz0bWXuCPup06IY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 913.9132387486536, + "y": 1100.0000000000002, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 79.07194519042969, + "height": 21.6, + "seed": 770796734, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259099222, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "user action", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s2nbjTVj0j-skA04MtKYA", + "originalText": "user action", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2750, + "versionNonce": 1730904391, + "index": "b1g", + "isDeleted": false, + "id": "0zX1qYHDPewklEOFvj4QD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2066, + "y": 900.0079999999998, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 148, + "height": 0, + "seed": 2138176546, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "psImpelHuue29n4JsmLkX", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "endBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -148, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2829, + "versionNonce": 1557774439, + "index": "b1h", + "isDeleted": false, + "id": "LTmzzMoXFrWHTp5lPxsng", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2065.7979507575274, + "y": 824.1373071797163, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 148.22061906179576, + "height": 54.571785959581575, + "seed": 1183485502, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "qvvo7HObesyo5ZT27b9sr", + "mode": "orbit", + "fixedPoint": [ + 0.2819480169665236, + 0.28194801696652405 + ] + }, + "endBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.7313028158508456, + 0.7313028158508417 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -148.22061906179576, + 54.571785959581575 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3303, + "versionNonce": 2092112775, + "index": "b1i", + "isDeleted": false, + "id": "S5dSkBXUSg76SDQt3W13H", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2065.9848293446635, + "y": 978.8319264049451, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 148.11159407854328, + "height": 55.936937986448584, + "seed": 575849314, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "hkW4E8W2PBqH1elRpqblc", + "mode": "orbit", + "fixedPoint": [ + 0.263554668335573, + 0.7364453316644302 + ] + }, + "endBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.7285815702860395, + 0.2714184297139582 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -148.11159407854328, + -55.936937986448584 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2923, + "versionNonce": 183767719, + "index": "b1k", + "isDeleted": false, + "id": "QWCS1GyzOCBXXYXqVNDpb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2174, + "y": 1100.0075555555554, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 102, + "height": 0.007555555555427418, + "seed": 598275710, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "bCFj-2psC1jO3ofEPISdO", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 102, + -0.007555555555427418 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 4702, + "versionNonce": 478109705, + "index": "b1l", + "isDeleted": false, + "id": "xp5it2Nn_WADNo0a81V51", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1959.8545088040914, + "y": 1146, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.08892368308420373, + "height": 88, + "seed": 1735607294, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774014713771, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ntHUF_yYTUblG1GM9xT3-", + "mode": "orbit", + "fixedPoint": [ + 0.263468761786106, + 0.736531238213891 + ] + }, + "endBinding": { + "elementId": "yI1dv38inyXae-rCzLZ84", + "mode": "orbit", + "fixedPoint": [ + 0.46137417468779485, + 0.0026775455914733125 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.08892368308420373, + 88 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3069, + "versionNonce": 1271846119, + "index": "b1n", + "isDeleted": false, + "id": "Ygnw-iaOoqppjkCrjH6gl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2279.7180712765544, + "y": 946, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.43237548727290687, + "height": 108, + "seed": 1281106338, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.8429679869254928, + 0.8429679869254898 + ] + }, + "endBinding": { + "elementId": "bCFj-2psC1jO3ofEPISdO", + "mode": "orbit", + "fixedPoint": [ + 0.2838647202008125, + 0.2838647202008161 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.43237548727290687, + 108 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3481, + "versionNonce": 1695653895, + "index": "b1q", + "isDeleted": false, + "id": "fB4icsfKClx9S5dbhDId4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2439.679796545497, + "y": 945.9999999999998, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.3218017959016066, + "height": 288, + "seed": 1158595582, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.42200923148452574, + 0.5779907685154712 + ] + }, + "endBinding": { + "elementId": "3Spp8mrcZg9MXepQ5drJ3", + "mode": "orbit", + "fixedPoint": [ + 0.7362375680767469, + 0.2637624319232509 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.3218017959016066, + 288 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3116, + "versionNonce": 1577977639, + "index": "b1r", + "isDeleted": false, + "id": "Ux5vG0eabsqv3OAl8vGxQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2499.5350654694867, + "y": 946, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.45923474792766683, + "height": 108, + "seed": 1168415678, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.2646730515914151, + 0.7353269484085843 + ] + }, + "endBinding": { + "elementId": "Rshmi9xEWpAp-k9_tQ5AL", + "mode": "orbit", + "fixedPoint": [ + 0.713455158767156, + 0.28654484123284474 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.45923474792766683, + 108 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3541, + "versionNonce": 1160809031, + "index": "b1s", + "isDeleted": false, + "id": "PXmySXcx7UP_RaaosnNEH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2339.506679793365, + "y": 946, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.9171734394067386, + "height": 288.28795138464466, + "seed": 1011916990, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774001483264, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uKguRheWdRNktVZka7Cdt", + "mode": "orbit", + "fixedPoint": [ + 0.685763013949529, + 0.6857630139495313 + ] + }, + "endBinding": { + "elementId": "DIW_5y3At3AC_jFTZsTtq", + "mode": "orbit", + "fixedPoint": [ + 0.08999449583777244, + 0.08999449583777276 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.9171734394067386, + 288.28795138464466 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3379, + "versionNonce": 984148583, + "index": "b1t", + "isDeleted": false, + "id": "kPLMsg-RaliXKURi5OIGS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2500, + "y": 1146, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 500, + "height": 88, + "seed": 229781374, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774014713773, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "yI1dv38inyXae-rCzLZ84", + "mode": "orbit", + "fixedPoint": [ + 0.2761596548004315, + -0.05999999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 54 + ], + [ + 500, + 54 + ], + [ + 500, + 88 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 54 + ], + "end": [ + 500, + 54 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 3156, + "versionNonce": 1480454503, + "index": "b1u", + "isDeleted": false, + "id": "G5RRJ-sHbq0MyY0OWoTEa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2020, + "y": 1600, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 280, + "height": 120.00000000000001, + "seed": 286090471, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "N85DhfU8Ko5wXfQUElHMA" + }, + { + "id": "7Wv5r4GRTEzCOmpbdVLLY", + "type": "arrow" + } + ], + "updated": 1774009346026, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3264, + "versionNonce": 891770663, + "index": "b1v", + "isDeleted": false, + "id": "N85DhfU8Ko5wXfQUElHMA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1967.1798782348633, + "y": 1619.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 174.35975646972656, + "height": 81, + "seed": 603860999, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Public facing apps, \nMarketing sites, \nE-commerce", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "G5RRJ-sHbq0MyY0OWoTEa", + "originalText": "Public facing apps, \nMarketing sites, \nE-commerce", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3169, + "versionNonce": 211802695, + "index": "b1x", + "isDeleted": false, + "id": "zw1OnftFPCIErhxZYatvj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2020, + "y": 1760, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 280, + "height": 120.00000000000001, + "seed": 1948636455, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "gDyGwT8kaMZIMnTuPT2jX" + }, + { + "id": "Vm4cm2vFmaSIcb8roRpsN", + "type": "arrow" + } + ], + "updated": 1774001862759, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3331, + "versionNonce": 1683683687, + "index": "b1y", + "isDeleted": false, + "id": "gDyGwT8kaMZIMnTuPT2jX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1947.3999099731445, + "y": 1779.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 134.79981994628906, + "height": 81, + "seed": 589207623, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Admin panels, \nDashboards, \nInternal tools", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "zw1OnftFPCIErhxZYatvj", + "originalText": "Admin panels, \nDashboards, \nInternal tools", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3172, + "versionNonce": 1369781383, + "index": "b1z", + "isDeleted": false, + "id": "3-icsfUAeu36tPJC_69eG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2020, + "y": 1920, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 280, + "height": 120.00000000000001, + "seed": 881769161, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "C7ostLTOsmDygsRiSLm7V" + }, + { + "id": "kPdEJajN4bnXHkVgszAYI", + "type": "arrow" + } + ], + "updated": 1774001862759, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3394, + "versionNonce": 205196199, + "index": "b20", + "isDeleted": false, + "id": "C7ostLTOsmDygsRiSLm7V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1954.2399215698242, + "y": 1939.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 148.47984313964844, + "height": 81, + "seed": 1918794153, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001862759, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Documentation, \nLanding pages, \nBlogs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "3-icsfUAeu36tPJC_69eG", + "originalText": "Documentation, \nLanding pages, \nBlogs", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2263, + "versionNonce": 1100277767, + "index": "b22", + "isDeleted": false, + "id": "7Wv5r4GRTEzCOmpbdVLLY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2274, + "y": 1660.012, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 248, + "height": 0, + "seed": 931025575, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "sksvzenYoNdUG2MJpEstb" + } + ], + "updated": 1774009346025, + "link": null, + "locked": false, + "startBinding": { + "elementId": "WTT7g6O0x3PLUV4L11yYe", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "G5RRJ-sHbq0MyY0OWoTEa", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 248, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 70, + "versionNonce": 1047080071, + "index": "b23", + "isDeleted": false, + "id": "sksvzenYoNdUG2MJpEstb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2219.1839447021484, + "y": 1638.412, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 138.36788940429688, + "height": 43.2, + "seed": 831219143, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009346027, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "SEO, public pages, \nfast first paint", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "7Wv5r4GRTEzCOmpbdVLLY", + "originalText": "SEO, public pages, \nfast first paint", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2384, + "versionNonce": 1617661415, + "index": "b24", + "isDeleted": false, + "id": "Vm4cm2vFmaSIcb8roRpsN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2274, + "y": 1820.0120000000002, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 248, + "height": 0, + "seed": 321740071, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "5RhTWGVwdV23C0AvAtrd_" + } + ], + "updated": 1774001862759, + "link": null, + "locked": false, + "startBinding": { + "elementId": "bY8JsyP2Uu1L362W7XrsJ", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "zw1OnftFPCIErhxZYatvj", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 248, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 108, + "versionNonce": 1517054183, + "index": "b25", + "isDeleted": false, + "id": "5RhTWGVwdV23C0AvAtrd_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1934.4959411621094, + "y": 2038.405875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 122.99188232421875, + "height": 43.2, + "seed": 133505095, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001750938, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Rich interactivity,\nno SEO needs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Vm4cm2vFmaSIcb8roRpsN", + "originalText": "Rich interactivity,\nno SEO needs", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2510, + "versionNonce": 182671145, + "index": "b26", + "isDeleted": false, + "id": "kPdEJajN4bnXHkVgszAYI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2274, + "y": 1980.012, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 248, + "height": 0, + "seed": 756789287, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "bi59zowpIsxsctKdZx0lH" + } + ], + "updated": 1774008217532, + "link": null, + "locked": false, + "startBinding": { + "elementId": "1KHHCNIJ_-2KOyBKP_j_D", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "3-icsfUAeu36tPJC_69eG", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 248, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 141, + "versionNonce": 677771145, + "index": "b27", + "isDeleted": false, + "id": "bi59zowpIsxsctKdZx0lH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1938.1759567260742, + "y": 2198.4120000000003, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 96.35191345214844, + "height": 43.2, + "seed": 379654983, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774001788637, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Pre-rendered\nat build time", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "kPdEJajN4bnXHkVgszAYI", + "originalText": "Pre-rendered\nat build time", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2218, + "versionNonce": 950802951, + "index": "b28", + "isDeleted": false, + "id": "aEhjZZlekcgPgfnKU7UX5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 2140, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 900, + "height": 500, + "seed": 481856841, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1241, + "versionNonce": 206127399, + "index": "b29", + "isDeleted": false, + "id": "RrKm8dlU5hillUfLXJwok", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2220, + "y": 2160, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 144.87188720703125, + "height": 37.800000000000004, + "seed": 1383838345, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Application", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Application", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1298, + "versionNonce": 1005880391, + "index": "b2A", + "isDeleted": false, + "id": "rVh5fFs_zeCz0NDSP_9or", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2220, + "y": 2700, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 167.35592651367188, + "height": 37.800000000000004, + "seed": 517779817, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Data Storage", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Data Storage", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1324, + "versionNonce": 1468687207, + "index": "b2B", + "isDeleted": false, + "id": "sSAwbXD8w7AISIvjQcW3H", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2260, + "y": 2980, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 230.77587890625, + "height": 37.800000000000004, + "seed": 598808935, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Managed Services", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Managed Services", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1971, + "versionNonce": 1062690439, + "index": "b2G", + "isDeleted": false, + "id": "APGpqtc4kzTKnbXytDAV4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2280, + "y": 2240, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 280, + "height": 100.00000000000001, + "seed": 923418503, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "zxnZ9dVWgwp3LNHr5uNA8" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1898, + "versionNonce": 370668967, + "index": "b2H", + "isDeleted": false, + "id": "zxnZ9dVWgwp3LNHr5uNA8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2206.1199264526367, + "y": 2276.5, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 132.23985290527344, + "height": 27, + "seed": 918992551, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "NestJS Service", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "APGpqtc4kzTKnbXytDAV4", + "originalText": "NestJS Service", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2035, + "versionNonce": 1928898759, + "index": "b2I", + "isDeleted": false, + "id": "HKRE7HgnoNbUgucrpMKZ4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2500, + "y": 2440, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 280, + "height": 100.00000000000001, + "seed": 824050537, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "8JJOzIysafPgG9zZg9yP7" + }, + { + "id": "ewncqWKY_RU739RLzxITN", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1962, + "versionNonce": 1402337255, + "index": "b2J", + "isDeleted": false, + "id": "8JJOzIysafPgG9zZg9yP7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2438.7599182128906, + "y": 2463, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 157.51983642578125, + "height": 54, + "seed": 2067508809, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "ORM Layer\nPrisma / Typeorm", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "HKRE7HgnoNbUgucrpMKZ4", + "originalText": "ORM Layer\nPrisma / Typeorm", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2255, + "versionNonce": 1308386055, + "index": "b2K", + "isDeleted": false, + "id": "nls1ujkELynLdHeusEb8c", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 2680, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 900, + "height": 240, + "seed": 2079562793, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 1105, + "versionNonce": 44591655, + "index": "b2L", + "isDeleted": false, + "id": "UPaOOxalHisiy8Ra1Rh6j", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2580, + "y": 2760, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 260, + "height": 120, + "seed": 1689356903, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "s48XmZz-cCYiyK8RL23tI" + }, + { + "id": "xofde1vhFDzGcnqt0vBPa", + "type": "arrow" + }, + { + "id": "jK2-CBw9X3yd0s4Z0ac5U", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1070, + "versionNonce": 1317440839, + "index": "b2M", + "isDeleted": false, + "id": "s48XmZz-cCYiyK8RL23tI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2531.0399169921875, + "y": 2793, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 162.079833984375, + "height": 54, + "seed": 184657287, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "PostgreSQL\nPrimary Database", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "UPaOOxalHisiy8Ra1Rh6j", + "originalText": "PostgreSQL\nPrimary Database", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1129, + "versionNonce": 1022577767, + "index": "b2R", + "isDeleted": false, + "id": "PMh8ei5QIZ2iRRpTH17Ty", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1980, + "y": 2760, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 260, + "height": 120, + "seed": 1332925799, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Xnm2qOLbYTXx-sdhCxj_k" + }, + { + "id": "gbfqoZ6LxYvW5Wxk9A6H9", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1090, + "versionNonce": 968566663, + "index": "b2S", + "isDeleted": false, + "id": "Xnm2qOLbYTXx-sdhCxj_k", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1929.549919128418, + "y": 2793, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 159.09983825683594, + "height": 54, + "seed": 1164021895, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Redis\nCache & Sessions", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "PMh8ei5QIZ2iRRpTH17Ty", + "originalText": "Redis\nCache & Sessions", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 1156, + "versionNonce": 52076199, + "index": "b2T", + "isDeleted": false, + "id": "FpYlRDsCyGz4GmFkusAx-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2280, + "y": 2760, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 260, + "height": 120, + "seed": 362582215, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "1HGGPRflevASUuOJNyIM2" + }, + { + "id": "ewncqWKY_RU739RLzxITN", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1120, + "versionNonce": 1539191239, + "index": "b2U", + "isDeleted": false, + "id": "1HGGPRflevASUuOJNyIM2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2223.4299240112305, + "y": 2793, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 146.85984802246094, + "height": 54, + "seed": 1232920551, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "MongoDB\nDocument Store", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "FpYlRDsCyGz4GmFkusAx-", + "originalText": "MongoDB\nDocument Store", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2267, + "versionNonce": 2093113575, + "index": "b2V", + "isDeleted": false, + "id": "efgiXsGHL4Rc1Gb4Zz7Si", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2600, + "y": 2960, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 900, + "height": 240, + "seed": 1758255303, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3237, + "versionNonce": 1202957319, + "index": "b2W", + "isDeleted": false, + "id": "dy1o7Q2QU3_qd5AsfOaTL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2500, + "y": 3040, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 120.00000000000001, + "seed": 476732361, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "zi7Yt0NOrCIVoGKRB7lfg" + }, + { + "id": "UjcxVWsI6az0L_6HaI5nm", + "type": "arrow" + }, + { + "id": "jK2-CBw9X3yd0s4Z0ac5U", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3347, + "versionNonce": 948867879, + "index": "b2X", + "isDeleted": false, + "id": "zi7Yt0NOrCIVoGKRB7lfg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2436.7299270629883, + "y": 3073, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 153.45985412597656, + "height": 54, + "seed": 1964713, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "GCP Cloud SQL\nDO Managed DB", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dy1o7Q2QU3_qd5AsfOaTL", + "originalText": "GCP Cloud SQL\nDO Managed DB", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3261, + "versionNonce": 398431815, + "index": "b2Y", + "isDeleted": false, + "id": "QvZ7Ef5fm8g72VzfKv-EV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2080, + "y": 3040, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 120.00000000000001, + "seed": 389354857, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "zwYvnmyZDXQpjx4__7oXq" + }, + { + "id": "UjcxVWsI6az0L_6HaI5nm", + "type": "arrow" + } + ], + "updated": 1774008570248, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3395, + "versionNonce": 1814246759, + "index": "b2Z", + "isDeleted": false, + "id": "zwYvnmyZDXQpjx4__7oXq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2046.379898071289, + "y": 3073, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 212.75979614257812, + "height": 54, + "seed": 1889566793, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 6, + "text": "Automated Backups\nPoint-in-Time Recovery", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QvZ7Ef5fm8g72VzfKv-EV", + "originalText": "Automated Backups\nPoint-in-Time Recovery", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 3585, + "versionNonce": 1265816190, + "index": "b2a", + "isDeleted": false, + "id": "gbfqoZ6LxYvW5Wxk9A6H9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2100, + "y": 2346, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 249.9000000000001, + "height": 408, + "seed": 908319273, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774270397646, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "PMh8ei5QIZ2iRRpTH17Ty", + "mode": "orbit", + "fixedPoint": [ + 0.4996153846153845, + -0.05 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 48 + ], + [ + 249.9000000000001, + 48 + ], + [ + 249.9000000000001, + 408 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 48 + ], + "end": [ + 249.89999999999998, + 48 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 3932, + "versionNonce": 1873459911, + "index": "b2c", + "isDeleted": false, + "id": "xofde1vhFDzGcnqt0vBPa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2400, + "y": 2546, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 50.10000000000002, + "height": 208, + "seed": 293423433, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "UPaOOxalHisiy8Ra1Rh6j", + "mode": "orbit", + "fixedPoint": [ + 0.4996153846153845, + -0.05 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 108 + ], + [ + -50.10000000000002, + 108 + ], + [ + -50.10000000000002, + 208 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 3965, + "versionNonce": 1412811239, + "index": "b2d", + "isDeleted": false, + "id": "ewncqWKY_RU739RLzxITN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2300, + "y": 2546, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 60, + "height": 208, + "seed": 1517679111, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "startBinding": { + "elementId": "HKRE7HgnoNbUgucrpMKZ4", + "mode": "orbit", + "fixedPoint": [ + 0.7142857142857143, + 1.0599999999999998 + ] + }, + "endBinding": { + "elementId": "FpYlRDsCyGz4GmFkusAx-", + "mode": "orbit", + "fixedPoint": [ + 0.15384615384615385, + -0.05 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 104 + ], + [ + 60, + 104 + ], + [ + 60, + 208 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 5124, + "versionNonce": 248640775, + "index": "b2e", + "isDeleted": false, + "id": "jK2-CBw9X3yd0s4Z0ac5U", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2400.73263748588, + "y": 2886, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.32175889652489786, + "height": 147.99999999999977, + "seed": 185335367, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008570248, + "link": null, + "locked": false, + "startBinding": { + "elementId": "UPaOOxalHisiy8Ra1Rh6j", + "mode": "orbit", + "fixedPoint": [ + 0.6891277544029676, + 0.6891277544029681 + ] + }, + "endBinding": { + "elementId": "dy1o7Q2QU3_qd5AsfOaTL", + "mode": "orbit", + "fixedPoint": [ + 0.35573018212803414, + 0.008759800033813764 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.32175889652489786, + 147.99999999999977 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5012, + "versionNonce": 1478945726, + "index": "b2f", + "isDeleted": false, + "id": "UjcxVWsI6az0L_6HaI5nm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2214, + "y": 3100.0120000000006, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 128, + "height": 0, + "seed": 572946985, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774257283486, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dy1o7Q2QU3_qd5AsfOaTL", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "QvZ7Ef5fm8g72VzfKv-EV", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 128, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 3284, + "versionNonce": 259390345, + "index": "b2g", + "isDeleted": false, + "id": "QDKrgXoYzxW_6h02DpoJO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4040, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1472086983, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "e7e9T33BDT_e_WzOPd4lv" + }, + { + "id": "_EIo38FQw0baMXgTpCIXe", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3368, + "versionNonce": 404726377, + "index": "b2h", + "isDeleted": false, + "id": "e7e9T33BDT_e_WzOPd4lv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4002.4799575805664, + "y": 3362.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 204.9599151611328, + "height": 75.60000000000001, + "seed": 1659908839, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Schema Change\nin Code", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QDKrgXoYzxW_6h02DpoJO", + "originalText": "Schema Change\nin Code", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3299, + "versionNonce": 1857121609, + "index": "b2i", + "isDeleted": false, + "id": "2Kwx1quK3_v4yfGJqBw15", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3640, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1437892137, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "bOQWslnzi24bAY2G47nXJ" + }, + { + "id": "_EIo38FQw0baMXgTpCIXe", + "type": "arrow" + }, + { + "id": "aBM1kXbeWH69UcTOtw5-8", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3415, + "versionNonce": 1787223081, + "index": "b2j", + "isDeleted": false, + "id": "bOQWslnzi24bAY2G47nXJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3622.1219177246094, + "y": 3362.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 244.24383544921875, + "height": 75.60000000000001, + "seed": 615829769, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Generate Migration\nFile", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "2Kwx1quK3_v4yfGJqBw15", + "originalText": "Generate Migration File", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3334, + "versionNonce": 1804300041, + "index": "b2k", + "isDeleted": false, + "id": "U3RO2YKWqrGaWzPq6LcPy", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3240, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 682990183, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Auapyjt5y0H1w5AEbZYXt" + }, + { + "id": "aBM1kXbeWH69UcTOtw5-8", + "type": "arrow" + }, + { + "id": "uMdt5yBO6-ev8g2hanyPl", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3473, + "versionNonce": 1211803113, + "index": "b2l", + "isDeleted": false, + "id": "Auapyjt5y0H1w5AEbZYXt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3219.517951965332, + "y": 3381.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 239.03590393066406, + "height": 37.800000000000004, + "seed": 1409529223, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Code Review in PR", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "U3RO2YKWqrGaWzPq6LcPy", + "originalText": "Code Review in PR", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3337, + "versionNonce": 2074083529, + "index": "b2m", + "isDeleted": false, + "id": "WVw7n0imHVChQpz-zrnUk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2840, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 666241959, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "3f6fRw814xs27QjfzsfWu" + }, + { + "id": "uMdt5yBO6-ev8g2hanyPl", + "type": "arrow" + }, + { + "id": "gRqvlsbSoNfeLFD9_OyJU", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3498, + "versionNonce": 324468649, + "index": "b2n", + "isDeleted": false, + "id": "3f6fRw814xs27QjfzsfWu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2812.909927368164, + "y": 3362.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 225.81985473632812, + "height": 75.60000000000001, + "seed": 342097607, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "CI Runs Migration\nTest", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "WVw7n0imHVChQpz-zrnUk", + "originalText": "CI Runs Migration Test", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3341, + "versionNonce": 1569399433, + "index": "b2o", + "isDeleted": false, + "id": "B6tFA9XpKJSR-qO_BQjNI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2440, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 907927177, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "upp7Cnfu5JSSURUveyw_z" + }, + { + "id": "gRqvlsbSoNfeLFD9_OyJU", + "type": "arrow" + }, + { + "id": "TdiXsRhXicldA23zict1b", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3528, + "versionNonce": 1459087721, + "index": "b2p", + "isDeleted": false, + "id": "upp7Cnfu5JSSURUveyw_z", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2412.559928894043, + "y": 3362.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 225.11985778808594, + "height": 75.60000000000001, + "seed": 97723753, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Deploy: Migration\nTest", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "B6tFA9XpKJSR-qO_BQjNI", + "originalText": "Deploy: Migration Test", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3386, + "versionNonce": 1491653705, + "index": "b2q", + "isDeleted": false, + "id": "kL-YTx0pzbfnlgxRJZ4mQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2040, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1723414279, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "8ndciMLppPXWTn_WRVcqq" + }, + { + "id": "TdiXsRhXicldA23zict1b", + "type": "arrow" + } + ], + "updated": 1774008877155, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3596, + "versionNonce": 121201449, + "index": "b2r", + "isDeleted": false, + "id": "8ndciMLppPXWTn_WRVcqq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2007.6739196777344, + "y": 3381.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 215.34783935546875, + "height": 37.800000000000004, + "seed": 346734119, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Start Application", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "kL-YTx0pzbfnlgxRJZ4mQ", + "originalText": "Start Application", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5196, + "versionNonce": 2119505417, + "index": "b2s", + "isDeleted": false, + "id": "_EIo38FQw0baMXgTpCIXe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3754, + "y": 3400.0114, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 108, + "height": 0.0006000000000767614, + "seed": 127577191, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QDKrgXoYzxW_6h02DpoJO", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "2Kwx1quK3_v4yfGJqBw15", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 108, + 0.0006000000000767614 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5325, + "versionNonce": 1094151401, + "index": "b2t", + "isDeleted": false, + "id": "aBM1kXbeWH69UcTOtw5-8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3354, + "y": 3400.0119999999997, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 108, + "height": 0.0005999999998493877, + "seed": 618577385, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2Kwx1quK3_v4yfGJqBw15", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "U3RO2YKWqrGaWzPq6LcPy", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 108, + -0.0005999999998493877 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5447, + "versionNonce": 1735124937, + "index": "b2u", + "isDeleted": false, + "id": "uMdt5yBO6-ev8g2hanyPl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2954, + "y": 3400.0114, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 108, + "height": 0.0006000000000767614, + "seed": 803267335, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "startBinding": { + "elementId": "U3RO2YKWqrGaWzPq6LcPy", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "WVw7n0imHVChQpz-zrnUk", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 108, + 0.0006000000000767614 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5509, + "versionNonce": 185468585, + "index": "b2v", + "isDeleted": false, + "id": "gRqvlsbSoNfeLFD9_OyJU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2554, + "y": 3400.0114000000003, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 108, + "height": 0.0005999999998493877, + "seed": 1916919753, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "startBinding": { + "elementId": "WVw7n0imHVChQpz-zrnUk", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "B6tFA9XpKJSR-qO_BQjNI", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 108, + 0.0005999999998493877 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5597, + "versionNonce": 1992903049, + "index": "b2w", + "isDeleted": false, + "id": "TdiXsRhXicldA23zict1b", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2154, + "y": 3400.0114, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 108, + "height": 0.0006000000000767614, + "seed": 573205321, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774008877155, + "link": null, + "locked": false, + "startBinding": { + "elementId": "B6tFA9XpKJSR-qO_BQjNI", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "kL-YTx0pzbfnlgxRJZ4mQ", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 108, + 0.0006000000000767614 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 2204, + "versionNonce": 392944233, + "index": "b2x", + "isDeleted": false, + "id": "9y8ASt-xsZqXhLCPLlQaw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4020, + "y": 720, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 960, + "height": 280, + "seed": 258290695, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1357, + "versionNonce": 666281289, + "index": "b2y", + "isDeleted": false, + "id": "iFbYC1xtsnyV56wFZGOJk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3660, + "y": 740, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 166.71192932128906, + "height": 37.800000000000004, + "seed": 654538855, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "CI (Every PR)", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "CI (Every PR)", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2433, + "versionNonce": 1948987721, + "index": "b2z", + "isDeleted": false, + "id": "8GZIc4BuJKRKcwhRxLZha", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4020, + "y": 1020, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 960, + "height": 259.99999999999994, + "seed": 643763719, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "Qo3fIchbHAs8wRbjlcUy1", + "type": "arrow" + } + ], + "updated": 1774013671490, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1439, + "versionNonce": 513976073, + "index": "b30", + "isDeleted": false, + "id": "QDL44XPeR11Lq62V1oLaq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3660, + "y": 1020, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 190.23191833496094, + "height": 37.800000000000004, + "seed": 2039902409, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "CD (On Merge)", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "CD (On Merge)", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3252, + "versionNonce": 61529577, + "index": "b31", + "isDeleted": false, + "id": "43omslhZI8xKSmrNIropM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4000, + "y": 800, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1723281671, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "I9BXOwuCIGMdDN-VEpioq", + "type": "text" + } + ], + "updated": 1774009904884, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3327, + "versionNonce": 1279867081, + "index": "b32", + "isDeleted": false, + "id": "I9BXOwuCIGMdDN-VEpioq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3963.4879302978516, + "y": 822.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 206.97586059570312, + "height": 75.60000000000001, + "seed": 383350823, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Lint\nESLint + Prettier", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "43omslhZI8xKSmrNIropM", + "originalText": "Lint\nESLint + Prettier", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3239, + "versionNonce": 1297283079, + "index": "b34", + "isDeleted": false, + "id": "T1msQ8aZGCopFQwKto7hl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3680, + "y": 800, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 280, + "height": 120.00000000000001, + "seed": 1924299977, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "NF7HDGeLt6PE4fhIZw7HE" + }, + { + "id": "ojB0zh0cF_feOHQbpn62A", + "type": "arrow" + }, + { + "id": "ljD0xTPk6zPUn691N8UR8", + "type": "arrow" + } + ], + "updated": 1774012153761, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3379, + "versionNonce": 1684299559, + "index": "b35", + "isDeleted": false, + "id": "NF7HDGeLt6PE4fhIZw7HE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3651.4259185791016, + "y": 822.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 222.85183715820312, + "height": 75.60000000000001, + "seed": 2059008937, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774012153761, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Test\nUnit + Integration", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "T1msQ8aZGCopFQwKto7hl", + "originalText": "Test\nUnit + Integration", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3293, + "versionNonce": 1773850631, + "index": "b36", + "isDeleted": false, + "id": "NjS4s_QyoDzLX5K3TSaNy", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3360, + "y": 800, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 120.00000000000001, + "seed": 519962151, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Nu4zjpdI3FdAEaCiIYKCx" + }, + { + "id": "L_13vDh3xCmnZRIY3j3D0", + "type": "arrow" + }, + { + "id": "ljD0xTPk6zPUn691N8UR8", + "type": "arrow" + } + ], + "updated": 1774010166006, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3407, + "versionNonce": 1328942153, + "index": "b37", + "isDeleted": false, + "id": "Nu4zjpdI3FdAEaCiIYKCx", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3347.203926086426, + "y": 822.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 254.40785217285156, + "height": 75.60000000000001, + "seed": 1930010951, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Build \nTypeScript + Docker", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NjS4s_QyoDzLX5K3TSaNy", + "originalText": "Build \nTypeScript + Docker", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3341, + "versionNonce": 790600489, + "index": "b38", + "isDeleted": false, + "id": "J9jAmeFAUEZXSavj3w02c", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3900, + "y": 1080, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 2135272585, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "HqH5ZQZP90i-w2EqePloN", + "type": "text" + }, + { + "id": "LHuqp7fSSWn2vxkR0lvCY", + "type": "arrow" + }, + { + "id": "Qo3fIchbHAs8wRbjlcUy1", + "type": "arrow" + }, + { + "id": "L_13vDh3xCmnZRIY3j3D0", + "type": "arrow" + } + ], + "updated": 1774009904884, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3447, + "versionNonce": 1018449417, + "index": "b39", + "isDeleted": false, + "id": "HqH5ZQZP90i-w2EqePloN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3834.0739669799805, + "y": 1102.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 148.14793395996094, + "height": 75.60000000000001, + "seed": 886125417, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Push Image\nto Registry", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "J9jAmeFAUEZXSavj3w02c", + "originalText": "Push Image\nto Registry", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3392, + "versionNonce": 1592763625, + "index": "b3A", + "isDeleted": false, + "id": "V-HAzhLBpupNZiBU9EC8S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3440, + "y": 1040, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 100, + "seed": 2043047911, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "_bTVz8nV593NUcofywEB3", + "type": "text" + }, + { + "id": "Qo3fIchbHAs8wRbjlcUy1", + "type": "arrow" + } + ], + "updated": 1774009904884, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3473, + "versionNonce": 291315657, + "index": "b3B", + "isDeleted": false, + "id": "_bTVz8nV593NUcofywEB3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3385.2619857788086, + "y": 1052.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 90.52397155761719, + "height": 75.60000000000001, + "seed": 1197333255, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Deploy\nto Dev", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "V-HAzhLBpupNZiBU9EC8S", + "originalText": "Deploy\nto Dev", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3383, + "versionNonce": 1377320617, + "index": "b3C", + "isDeleted": false, + "id": "O89QCEqAzK2HrnCPdbr8o", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3440, + "y": 1160, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 100, + "seed": 249320521, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "3iwQos5XOMUW6SGCuSOlJ", + "type": "text" + }, + { + "id": "LHuqp7fSSWn2vxkR0lvCY", + "type": "arrow" + } + ], + "updated": 1774009904884, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3472, + "versionNonce": 1338802569, + "index": "b3D", + "isDeleted": false, + "id": "3iwQos5XOMUW6SGCuSOlJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3386.2839736938477, + "y": 1172.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 92.56794738769531, + "height": 75.60000000000001, + "seed": 851239721, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Deploy\nto Prod", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "O89QCEqAzK2HrnCPdbr8o", + "originalText": "Deploy\nto Prod", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5254, + "versionNonce": 1593565767, + "index": "b3E", + "isDeleted": false, + "id": "ojB0zh0cF_feOHQbpn62A", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3720, + "y": 860.0102000000004, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 34, + "height": 0.0015299999996614133, + "seed": 48825289, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774012153762, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "T1msQ8aZGCopFQwKto7hl", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 34, + 0.0015299999996614133 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5311, + "versionNonce": 502661479, + "index": "b3F", + "isDeleted": false, + "id": "ljD0xTPk6zPUn691N8UR8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3394, + "y": 860.0120000000002, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 28, + "height": 0, + "seed": 222932167, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774012153762, + "link": null, + "locked": false, + "startBinding": { + "elementId": "T1msQ8aZGCopFQwKto7hl", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "NjS4s_QyoDzLX5K3TSaNy", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 28, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5902, + "versionNonce": 669196841, + "index": "b3H", + "isDeleted": false, + "id": "Qo3fIchbHAs8wRbjlcUy1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3614, + "y": 1139.9, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 168, + "height": 39.90000000000009, + "seed": 1749886855, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "startBinding": { + "elementId": "J9jAmeFAUEZXSavj3w02c", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "endBinding": { + "elementId": "V-HAzhLBpupNZiBU9EC8S", + "mode": "orbit", + "fixedPoint": [ + -0.03, + 0.6 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 84, + 0 + ], + [ + 84, + -39.90000000000009 + ], + [ + 168, + -39.90000000000009 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 5912, + "versionNonce": 24048905, + "index": "b3I", + "isDeleted": false, + "id": "LHuqp7fSSWn2vxkR0lvCY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3614, + "y": 1160, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 168, + "height": 40, + "seed": 1477725863, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774009904884, + "link": null, + "locked": false, + "startBinding": { + "elementId": "J9jAmeFAUEZXSavj3w02c", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.6666666666666666 + ] + }, + "endBinding": { + "elementId": "O89QCEqAzK2HrnCPdbr8o", + "mode": "orbit", + "fixedPoint": [ + -0.03, + 0.4 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 84, + 0 + ], + [ + 84, + 40 + ], + [ + 168, + 40 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 6013, + "versionNonce": 1562942121, + "index": "b3J", + "isDeleted": false, + "id": "L_13vDh3xCmnZRIY3j3D0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3220.1, + "y": 926, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 540, + "height": 148, + "seed": 616133287, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774012217679, + "link": null, + "locked": false, + "startBinding": { + "elementId": "NjS4s_QyoDzLX5K3TSaNy", + "mode": "orbit", + "fixedPoint": [ + 0.49964285714285706, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "J9jAmeFAUEZXSavj3w02c", + "mode": "orbit", + "fixedPoint": [ + 0.49964285714285706, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 34 + ], + [ + -540, + 34 + ], + [ + -540, + 148 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 34 + ], + "end": [ + -540, + 34 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 3331, + "versionNonce": 1752942185, + "index": "b3R", + "isDeleted": false, + "id": "Vuo3hctmaVqxBr33lVM8W", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3800, + "y": 3060, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 306, + "height": 120.00000000000001, + "seed": 719374985, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "ISpZDKVHw0b3N6sstHW_G", + "type": "text" + }, + { + "id": "gSzyiqIOIf_dkEgIAW0Jh", + "type": "arrow" + } + ], + "updated": 1774010077509, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3445, + "versionNonce": 669585737, + "index": "b3S", + "isDeleted": false, + "id": "ISpZDKVHw0b3N6sstHW_G", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3755.863945007324, + "y": 3082.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 217.72789001464844, + "height": 75.60000000000001, + "seed": 995660137, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774010077509, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "develop branch\nDev Environment", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Vuo3hctmaVqxBr33lVM8W", + "originalText": "develop branch\nDev Environment", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3365, + "versionNonce": 1697251369, + "index": "b3T", + "isDeleted": false, + "id": "_czPQc3pt9PxdyraiDNmu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3460, + "y": 3060, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 306, + "height": 120.00000000000001, + "seed": 989101129, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "JFetc81oAeYP6hvZc6Yo_" + }, + { + "id": "gSzyiqIOIf_dkEgIAW0Jh", + "type": "arrow" + } + ], + "updated": 1774010077509, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3543, + "versionNonce": 1848251145, + "index": "b3U", + "isDeleted": false, + "id": "JFetc81oAeYP6hvZc6Yo_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3439.7059173583984, + "y": 3082.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 265.4118347167969, + "height": 75.60000000000001, + "seed": 2039483177, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774010077509, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "staging branch\nStaging Environment", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_czPQc3pt9PxdyraiDNmu", + "originalText": "staging branch\nStaging Environment", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5403, + "versionNonce": 2033511335, + "index": "b3X", + "isDeleted": false, + "id": "gSzyiqIOIf_dkEgIAW0Jh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3488, + "y": 3120.012, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 22, + "height": 0, + "seed": 845385673, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774010166776, + "link": null, + "locked": false, + "startBinding": { + "elementId": "Vuo3hctmaVqxBr33lVM8W", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "_czPQc3pt9PxdyraiDNmu", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 22, + 0 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 3378, + "versionNonce": 1508222153, + "index": "b3Z", + "isDeleted": false, + "id": "Qp50K0eLKFTVRCzoEOijs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3120, + "y": 3060, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 306, + "height": 120.00000000000001, + "seed": 564545799, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "C3kDyQ0yFcrQNVJmdTVcl" + }, + { + "id": "4t8JZ6s7-ZNpWflAxKGNc", + "type": "arrow" + } + ], + "updated": 1774010077509, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3580, + "versionNonce": 1632117673, + "index": "b3a", + "isDeleted": false, + "id": "C3kDyQ0yFcrQNVJmdTVcl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3044.7419509887695, + "y": 3082.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 155.48390197753906, + "height": 75.60000000000001, + "seed": 1411747879, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774010077509, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "main branch\nProduction", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Qp50K0eLKFTVRCzoEOijs", + "originalText": "main branch\nProduction", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5579, + "versionNonce": 431474313, + "index": "b3b", + "isDeleted": false, + "id": "4t8JZ6s7-ZNpWflAxKGNc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -3148, + "y": 3120.013174423788, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 22, + "height": 0.0009227615478266671, + "seed": 1842222633, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774010077509, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "Qp50K0eLKFTVRCzoEOijs", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 22, + -0.0009227615478266671 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "xoeHIbs3NO0NBL9nOuwlz", + "type": "diamond", + "x": -6460, + "y": 1240, + "width": 380, + "height": 363.47826086956525, + "angle": 0, + "strokeColor": "#ff5f00", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3i", + "roundness": { + "type": 2 + }, + "seed": 552083657, + "version": 367, + "versionNonce": 1162262793, + "isDeleted": false, + "boundElements": [ + { + "id": "K2JtNhRHAu1t6PQjmO41W", + "type": "arrow" + }, + { + "id": "bCaBqY1ZN6WRysnJKEe75", + "type": "arrow" + } + ], + "updated": 1774014953459, + "link": null, + "locked": false + }, + { + "id": "UpINXTUZPfzTXAZ8cAMvZ", + "type": "text", + "x": -6433, + "y": 1380, + "width": 320, + "height": 70, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3k", + "roundness": null, + "seed": 1981933735, + "version": 356, + "versionNonce": 1134815271, + "isDeleted": false, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "text": "Enterprise client?\nComplex scaling needs?", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Enterprise client?\nComplex scaling needs?", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "6vVf9fBrEkUmNj3gaInlF", + "type": "diamond", + "x": -6160, + "y": 1540, + "width": 380, + "height": 363.47826086956525, + "angle": 0, + "strokeColor": "#ff5f00", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3l", + "roundness": { + "type": 2 + }, + "seed": 1651889353, + "version": 387, + "versionNonce": 1653656265, + "isDeleted": false, + "boundElements": [ + { + "id": "x9AwkFTtEY0_rgRk3lZja", + "type": "arrow" + } + ], + "updated": 1774014953459, + "link": null, + "locked": false + }, + { + "id": "xkkKqC4o6Lrew750C9yKz", + "type": "text", + "x": -6120, + "y": 1680, + "width": 320, + "height": 70, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3m", + "roundness": null, + "seed": 764831913, + "version": 438, + "versionNonce": 933710439, + "isDeleted": false, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "text": "Tight budget?\nSimple infrastructure?", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Tight budget?\nSimple infrastructure?", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "qASaL0dPeyvTMYK-3ehh8", + "type": "diamond", + "x": -6460, + "y": 1820, + "width": 380, + "height": 363.47826086956525, + "angle": 0, + "strokeColor": "#ff5f00", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3n", + "roundness": { + "type": 2 + }, + "seed": 483521319, + "version": 390, + "versionNonce": 2034197895, + "isDeleted": false, + "boundElements": [ + { + "id": "FoNMkjaf6Ow0LLcIRiye1", + "type": "arrow" + }, + { + "id": "jgUQFrjvpmLmQumfalgwF", + "type": "arrow" + }, + { + "id": "SqCN0LiQsxOLsoNyFHydI", + "type": "arrow" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false + }, + { + "id": "91uk8KMjIBLwT80rSKWJo", + "type": "text", + "x": -6420, + "y": 1980, + "width": 320, + "height": 35, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3o", + "roundness": null, + "seed": 522994889, + "version": 467, + "versionNonce": 57089191, + "isDeleted": false, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "text": "Client preference?", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Client preference?", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "9RfGc7zRAXb8fLMqRaI7Q", + "type": "diamond", + "x": -6460, + "y": 820, + "width": 380, + "height": 363.47826086956525, + "angle": 0, + "strokeColor": "#ff5f00", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3p", + "roundness": { + "type": 2 + }, + "seed": 1695144681, + "version": 404, + "versionNonce": 1506471879, + "isDeleted": false, + "boundElements": [ + { + "id": "K2JtNhRHAu1t6PQjmO41W", + "type": "arrow" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false + }, + { + "id": "7AU_Qjrr3d9E0135ZMybH", + "type": "text", + "x": -6420, + "y": 980, + "width": 320, + "height": 35, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b3q", + "roundness": null, + "seed": 728727911, + "version": 379, + "versionNonce": 1451712231, + "isDeleted": false, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "text": "New Project", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "New Project", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 3506, + "versionNonce": 1546185223, + "index": "b3r", + "isDeleted": false, + "id": "K2JtNhRHAu1t6PQjmO41W", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6269, + "y": 1172.1032608695652, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0, + "height": 79.27173913043475, + "seed": 2009134857, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "9RfGc7zRAXb8fLMqRaI7Q", + "mode": "orbit", + "fixedPoint": [ + 0.5026315789473684, + 0.9687051435406698 + ] + }, + "endBinding": { + "elementId": "xoeHIbs3NO0NBL9nOuwlz", + "mode": "orbit", + "fixedPoint": [ + 0.5026315789473684, + 0.03129485645933014 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 79.27173913043475 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 3444, + "versionNonce": 1202458919, + "index": "b3s", + "isDeleted": false, + "id": "qHkFasVTce0YasMELHeDW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6700, + "y": 2420, + "strokeColor": "#ffffff", + "backgroundColor": "#2f9e44", + "width": 280, + "height": 124, + "seed": 838977095, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "KQbSeq6QKhaDt6QwCOU3S", + "type": "text" + }, + { + "id": "FoNMkjaf6Ow0LLcIRiye1", + "type": "arrow" + }, + { + "id": "bCaBqY1ZN6WRysnJKEe75", + "type": "arrow" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3535, + "versionNonce": 578638919, + "index": "b3t", + "isDeleted": false, + "id": "KQbSeq6QKhaDt6QwCOU3S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6646.981956481934, + "y": 2444.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 173.9639129638672, + "height": 75.60000000000001, + "seed": 1587504487, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google Cloud\nPlatform", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "qHkFasVTce0YasMELHeDW", + "originalText": "Google Cloud Platform", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3541, + "versionNonce": 343487335, + "index": "b3w", + "isDeleted": false, + "id": "MKxnLyxZhG8X4uwvmBntn", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6120, + "y": 2420, + "strokeColor": "#ffffff", + "backgroundColor": "#1677fa", + "width": 280, + "height": 124, + "seed": 252525673, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "2psgC1eIz9yoUagOs2rpJ", + "type": "text" + }, + { + "id": "jgUQFrjvpmLmQumfalgwF", + "type": "arrow" + }, + { + "id": "x9AwkFTtEY0_rgRk3lZja", + "type": "arrow" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3620, + "versionNonce": 367799943, + "index": "b3x", + "isDeleted": false, + "id": "2psgC1eIz9yoUagOs2rpJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6065.805953979492, + "y": 2463.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 171.61190795898438, + "height": 37.800000000000004, + "seed": 685492041, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774014058688, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Digital Ocean", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MKxnLyxZhG8X4uwvmBntn", + "originalText": "Digital Ocean", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2889, + "versionNonce": 1637008807, + "index": "b3y", + "isDeleted": false, + "id": "bCaBqY1ZN6WRysnJKEe75", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6452.796759798022, + "y": 1429.5282954913587, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 136.53037711536746, + "height": 984.4717045086413, + "seed": 275325255, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "QHUZ9P0w7Lbi3DOKQsyUp" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "xoeHIbs3NO0NBL9nOuwlz", + "mode": "orbit", + "fixedPoint": [ + 0.03141447368421053, + 0.5007177033492822 + ] + }, + "endBinding": { + "elementId": "qHkFasVTce0YasMELHeDW", + "mode": "orbit", + "fixedPoint": [ + 0.38829280327185, + 0.3882928032718529 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -107.20324020197802, + 170.47170450864132 + ], + [ + -136.53037711536746, + 984.4717045086413 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 38, + "versionNonce": 1152234537, + "index": "b3z", + "isDeleted": false, + "id": "QHUZ9P0w7Lbi3DOKQsyUp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -525.4239883422852, + "y": 1601.1, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 50.84797668457031, + "height": 37.800000000000004, + "seed": 1298358375, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013895950, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "YES", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bCaBqY1ZN6WRysnJKEe75", + "originalText": "YES", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 3013, + "versionNonce": 871189513, + "index": "b40", + "isDeleted": false, + "id": "kXQdq3G4WAGQbPFFB_18y", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7260, + "y": 2280, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.00737878057527, + "height": 119.46951389826222, + "seed": 1715600967, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "bk2jk8nP9LirORIhFUZkr" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 100, + 60 + ], + [ + 116.00737878057527, + 119.46951389826222 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 43, + "versionNonce": 539162665, + "index": "b41", + "isDeleted": false, + "id": "bk2jk8nP9LirORIhFUZkr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 278.8320083618164, + "y": 2021.1, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.33598327636719, + "height": 37.800000000000004, + "seed": 236494183, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774010882478, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "NO", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "kXQdq3G4WAGQbPFFB_18y", + "originalText": "NO", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 3018, + "versionNonce": 2057095143, + "index": "b42", + "isDeleted": false, + "id": "FoNMkjaf6Ow0LLcIRiye1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6407.745882053274, + "y": 2060.03244011728, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 100.44208351969189, + "height": 353.96755988272025, + "seed": 1169968487, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "Y0H3ZBF4FHAYAi1pi5EiR" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "qASaL0dPeyvTMYK-3ehh8", + "mode": "orbit", + "fixedPoint": [ + 0.3143734965565803, + 0.5001 + ] + }, + "endBinding": { + "elementId": "qHkFasVTce0YasMELHeDW", + "mode": "orbit", + "fixedPoint": [ + 0.6845832463926597, + -0.013648102197550778 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -92.25411794672597, + 79.9675598827198 + ], + [ + -100.44208351969189, + 353.96755988272025 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 46, + "versionNonce": 1966135943, + "index": "b43", + "isDeleted": false, + "id": "Y0H3ZBF4FHAYAi1pi5EiR", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -468.573989868164, + "y": 2141.1, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 57.147979736328125, + "height": 37.800000000000004, + "seed": 599525511, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013849527, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "GCP", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "FoNMkjaf6Ow0LLcIRiye1", + "originalText": "GCP", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 3223, + "versionNonce": 195638023, + "index": "b44", + "isDeleted": false, + "id": "jgUQFrjvpmLmQumfalgwF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6126.2850767177115, + "y": 2054.431465991508, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 118.81943014949441, + "height": 359.5685340084924, + "seed": 1951021577, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "u4mwwEp5WrnXm5hiN619J" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "qASaL0dPeyvTMYK-3ehh8", + "mode": "orbit", + "fixedPoint": [ + 0.738688249705512, + 0.5001 + ] + }, + "endBinding": { + "elementId": "MKxnLyxZhG8X4uwvmBntn", + "mode": "orbit", + "fixedPoint": [ + 0.4119690500006444, + 0.41196905000064393 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 106.28507671771166, + 105.56853400849195 + ], + [ + 118.81943014949441, + 359.5685340084924 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 66, + "versionNonce": 2024068425, + "index": "b45", + "isDeleted": false, + "id": "u4mwwEp5WrnXm5hiN619J", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -13.697982788085994, + "y": 2122.2, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 67.39596557617188, + "height": 75.60000000000001, + "seed": 82317545, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013864547, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "DO /\nNone", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jgUQFrjvpmLmQumfalgwF", + "originalText": "DO /\nNone", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 3359, + "versionNonce": 305871399, + "index": "b46", + "isDeleted": false, + "id": "SqCN0LiQsxOLsoNyFHydI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6080, + "y": 1800, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 91.02314562431263, + "height": 106.01174817175843, + "seed": 1174017255, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "g-340L74I7lQVBryBPOi5" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "qASaL0dPeyvTMYK-3ehh8", + "mode": "orbit", + "fixedPoint": [ + 0.5905492971728062, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -60, + 60 + ], + [ + -91.02314562431263, + 106.01174817175843 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 54, + "versionNonce": 107883241, + "index": "b47", + "isDeleted": false, + "id": "g-340L74I7lQVBryBPOi5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 265.09090390712885, + "y": 2406.6938690560446, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.33598327636719, + "height": 37.800000000000004, + "seed": 2010439687, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774010975677, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "NO", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "SqCN0LiQsxOLsoNyFHydI", + "originalText": "NO", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2478, + "versionNonce": 54484295, + "index": "b4A", + "isDeleted": false, + "id": "x9AwkFTtEY0_rgRk3lZja", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5901.129729011647, + "y": 1846.8572839053331, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.830769328918251, + "height": 567.1427160946669, + "seed": 1043160039, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "fQGDgioOViiH1lMnc-jWB" + } + ], + "updated": 1774014058688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "6vVf9fBrEkUmNj3gaInlF", + "mode": "orbit", + "fixedPoint": [ + 0.681719723517705, + 0.5001 + ] + }, + "endBinding": { + "elementId": "MKxnLyxZhG8X4uwvmBntn", + "mode": "orbit", + "fixedPoint": [ + 0.7785374512967347, + 0.22146254870326557 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.830769328918251, + 567.1427160946669 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 35, + "versionNonce": 1814608745, + "index": "b4B", + "isDeleted": false, + "id": "fQGDgioOViiH1lMnc-jWB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 353.2444579847708, + "y": 2561.3298066287225, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 50.84797668457031, + "height": 37.800000000000004, + "seed": 940001031, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774011048289, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "YES", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "x9AwkFTtEY0_rgRk3lZja", + "originalText": "YES", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2397, + "versionNonce": 1243739753, + "index": "b4C", + "isDeleted": false, + "id": "a8xymVQj2f9sSRIC63-Ag", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5560, + "y": 2260, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1400, + "height": 200, + "seed": 1026213479, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2415, + "versionNonce": 1430864201, + "index": "b4D", + "isDeleted": false, + "id": "suNkGF8RkrzxID8GObUTr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5560, + "y": 1900, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1220, + "height": 320, + "seed": 138530249, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1484, + "versionNonce": 1459892265, + "index": "b4E", + "isDeleted": false, + "id": "B7o1UYzw5xx3MTe9Rlkii", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5500, + "y": 2280, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 99.25994873046875, + "height": 37.800000000000004, + "seed": 2092477289, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Storage", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Storage", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1487, + "versionNonce": 87966473, + "index": "b4F", + "isDeleted": false, + "id": "VPgIKH-_OnD3vtLP4Wnne", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5500, + "y": 1920, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 137.64794921875, + "height": 37.800000000000004, + "seed": 201548969, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Data Layer", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Data Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2470, + "versionNonce": 1282603497, + "index": "b4G", + "isDeleted": false, + "id": "axVJn-jsv1SgbORYiVNz8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5560, + "y": 1120, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 680, + "height": 740, + "seed": 2094752809, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 4387, + "versionNonce": 2108544201, + "index": "b4H", + "isDeleted": false, + "id": "jielllMGu8NhLVJ7xTapl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4860.1, + "y": 1026, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 279.9, + "height": 188, + "seed": 670088359, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "YEVPMPsYYw1DMt-h6LSk1", + "mode": "orbit", + "fixedPoint": [ + 0.6521739130434783, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 14 + ], + [ + -279.9, + 14 + ], + [ + -279.9, + 188 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 14 + ], + "end": [ + -279.9, + 14 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 2636, + "versionNonce": 1015698345, + "index": "b4I", + "isDeleted": false, + "id": "9vEMqQ2tCBkgEdowZkfY1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5560, + "y": 820, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1400, + "height": 260, + "seed": 227475113, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2504, + "versionNonce": 758380169, + "index": "b4J", + "isDeleted": false, + "id": "Rck9T5zDsrKDmY6zHRYPk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4840, + "y": 1120, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 680, + "height": 740, + "seed": 84935431, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1522, + "versionNonce": 1650867561, + "index": "b4K", + "isDeleted": false, + "id": "Fmd1_pKSjSRu40MG2QbCU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4940, + "y": 840, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 151.81591796875, + "height": 37.800000000000004, + "seed": 465332233, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Client Layer", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Client Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1537, + "versionNonce": 191670345, + "index": "b4L", + "isDeleted": false, + "id": "YRly0mw1pCUaIHBEUMMha", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5500, + "y": 1140, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 122.55595397949219, + "height": 37.800000000000004, + "seed": 379223529, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "API Layer", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "API Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1566, + "versionNonce": 1646442281, + "index": "b4M", + "isDeleted": false, + "id": "Ex3arIAGhmJ4qq1x5rC7B", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4580, + "y": 1140, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 221.7318572998047, + "height": 37.800000000000004, + "seed": 1637412009, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Application Layer", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Application Layer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3373, + "versionNonce": 1492380169, + "index": "b4N", + "isDeleted": false, + "id": "JQk-e3Od1od66GryemVE0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5440, + "y": 900, + "strokeColor": "#ffffff", + "backgroundColor": "#a18072", + "width": 280, + "height": 120.00000000000001, + "seed": 1314090983, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "w3--lYgCwrY3mtiqsTESa", + "type": "text" + }, + { + "id": "uYetgu6N8TOvRgyJCzGLH", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3451, + "versionNonce": 148619497, + "index": "b4O", + "isDeleted": false, + "id": "w3--lYgCwrY3mtiqsTESa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5398.853958129883, + "y": 941.0999999999999, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 197.70791625976562, + "height": 37.800000000000004, + "seed": 38460167, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Web App / SPA", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "JQk-e3Od1od66GryemVE0", + "originalText": "Web App / SPA", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3382, + "versionNonce": 1600502729, + "index": "b4P", + "isDeleted": false, + "id": "Y6pLKGCw7FLovzMu4v--E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5000, + "y": 900, + "strokeColor": "#ffffff", + "backgroundColor": "#a18072", + "width": 280, + "height": 120.00000000000001, + "seed": 1155932777, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "9Gwv-ot6N2WYSlxJfwrah", + "type": "text" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3485, + "versionNonce": 212687529, + "index": "b4Q", + "isDeleted": false, + "id": "9Gwv-ot6N2WYSlxJfwrah", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4933.359954833984, + "y": 941.0999999999999, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 146.71990966796875, + "height": 37.800000000000004, + "seed": 1051192649, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Mobile App", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Y6pLKGCw7FLovzMu4v--E", + "originalText": "Mobile App", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3401, + "versionNonce": 828251529, + "index": "b4R", + "isDeleted": false, + "id": "C9ti1X8WktHvKDlWdpNOY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4560, + "y": 900, + "strokeColor": "#ffffff", + "backgroundColor": "#a18072", + "width": 280, + "height": 120.00000000000001, + "seed": 811003977, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "21mfA3T2yfAbn9uKQzttZ", + "type": "text" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3521, + "versionNonce": 1286833257, + "index": "b4S", + "isDeleted": false, + "id": "21mfA3T2yfAbn9uKQzttZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4540.609931945801, + "y": 941.0999999999999, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 241.21986389160156, + "height": 37.800000000000004, + "seed": 42204969, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "External Consumer", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "C9ti1X8WktHvKDlWdpNOY", + "originalText": "External Consumer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3385, + "versionNonce": 1786318665, + "index": "b4T", + "isDeleted": false, + "id": "YEVPMPsYYw1DMt-h6LSk1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5440, + "y": 1220, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 460, + "height": 120.00000000000001, + "seed": 6358727, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "omsbCzGayEZl4x84LngPg", + "type": "arrow" + }, + { + "id": "jielllMGu8NhLVJ7xTapl", + "type": "arrow" + }, + { + "id": "uYetgu6N8TOvRgyJCzGLH", + "type": "arrow" + }, + { + "id": "W0WAvpfTEAOhN67ZBU1v-", + "type": "arrow" + }, + { + "id": "gEMWh6NXTAz3Xmot6DUlO", + "type": "text" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3543, + "versionNonce": 285883945, + "index": "b4U", + "isDeleted": false, + "id": "gEMWh6NXTAz3Xmot6DUlO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5300.509963989258, + "y": 1242.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 181.01992797851562, + "height": 75.60000000000001, + "seed": 272799207, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "API Gateway /\nLoad Balancer", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "YEVPMPsYYw1DMt-h6LSk1", + "originalText": "API Gateway /\nLoad Balancer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3450, + "versionNonce": 1867682057, + "index": "b4b", + "isDeleted": false, + "id": "b008uK7WcSm53NPiSaBMi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4740, + "y": 1220, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 460, + "height": 120.00000000000001, + "seed": 176092297, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "xyrlwpnnBxZa4LLAror9B" + }, + { + "id": "W0WAvpfTEAOhN67ZBU1v-", + "type": "arrow" + }, + { + "id": "rspg9J1pILn8IK31qMo9V", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3584, + "versionNonce": 1254983657, + "index": "b4c", + "isDeleted": false, + "id": "xyrlwpnnBxZa4LLAror9B", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4647.605926513672, + "y": 1261.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 275.21185302734375, + "height": 37.800000000000004, + "seed": 430013289, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Guards & Middleware", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "b008uK7WcSm53NPiSaBMi", + "originalText": "Guards & Middleware", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3450, + "versionNonce": 763798217, + "index": "b4d", + "isDeleted": false, + "id": "NPcgzotrcXnsjzhddi0G3", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4740, + "y": 1380, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 460, + "height": 120.00000000000001, + "seed": 409978919, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5RZW4o0iEROMMWicKpdwa" + }, + { + "id": "86nTXYTzYBBsCXUq5vu-z", + "type": "arrow" + }, + { + "id": "Qo_vDm6mdU7PyJFlqIwSW", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3604, + "versionNonce": 1410949545, + "index": "b4e", + "isDeleted": false, + "id": "5RZW4o0iEROMMWicKpdwa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4612.213935852051, + "y": 1421.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 204.42787170410156, + "height": 37.800000000000004, + "seed": 800205639, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Validation Pipes", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NPcgzotrcXnsjzhddi0G3", + "originalText": "Validation Pipes", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3470, + "versionNonce": 1538344073, + "index": "b4f", + "isDeleted": false, + "id": "ibVvxd27TveKHay4jeOEi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4740, + "y": 1540, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 460, + "height": 120.00000000000001, + "seed": 49072201, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jkzu4VT_iXZR0R5mxqLXU" + }, + { + "id": "86nTXYTzYBBsCXUq5vu-z", + "type": "arrow" + }, + { + "id": "vjQKFEiN2SdKX_ffoHoeI", + "type": "arrow" + }, + { + "id": "Gv2BWIk7nqshrAH-SZMgP", + "type": "arrow" + }, + { + "id": "l0z1zPuhs6p8ZTiIZcSEo", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3631, + "versionNonce": 805948265, + "index": "b4g", + "isDeleted": false, + "id": "jkzu4VT_iXZR0R5mxqLXU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4603.687934875488, + "y": 1581.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 187.37586975097656, + "height": 37.800000000000004, + "seed": 882825001, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Business Logic", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ibVvxd27TveKHay4jeOEi", + "originalText": "Business Logic", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3484, + "versionNonce": 963540553, + "index": "b4h", + "isDeleted": false, + "id": "BhVJJ5nBZINfY5FZQ7wXT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4660, + "y": 1720, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 320, + "height": 120.00000000000001, + "seed": 1119833353, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "q3cc7TPpQHkVr7EpDSDzr" + }, + { + "id": "vjQKFEiN2SdKX_ffoHoeI", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3672, + "versionNonce": 1253754153, + "index": "b4i", + "isDeleted": false, + "id": "q3cc7TPpQHkVr7EpDSDzr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4632.4678955078125, + "y": 1761.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 264.935791015625, + "height": 37.800000000000004, + "seed": 155370473, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Interceptors & Filters", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "BhVJJ5nBZINfY5FZQ7wXT", + "originalText": "Interceptors & Filters", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3451, + "versionNonce": 1331312649, + "index": "b4j", + "isDeleted": false, + "id": "xIn0URm3b-fP982jJYyCL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4740, + "y": 2020, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 360, + "height": 120.00000000000001, + "seed": 244673127, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "Zs4NhrmZt4TofyYWUOIta", + "type": "text" + }, + { + "id": "WoACknI0HVTCC-IAmWk4K", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3556, + "versionNonce": 961040105, + "index": "b4k", + "isDeleted": false, + "id": "Zs4NhrmZt4TofyYWUOIta", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4656.711952209473, + "y": 2042.1999999999998, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 193.4239044189453, + "height": 75.60000000000001, + "seed": 225019271, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "ORM - Prisma /\nTypeORM", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "xIn0URm3b-fP982jJYyCL", + "originalText": "ORM - Prisma /\nTypeORM", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3429, + "versionNonce": 789613001, + "index": "b4l", + "isDeleted": false, + "id": "5iwdo2T6Mu66eQsc-oiKh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5140, + "y": 2020, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 360, + "height": 120.00000000000001, + "seed": 365945513, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "S7IJ0USPv5fLlngY-LaVx", + "type": "text" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3550, + "versionNonce": 2043570345, + "index": "b4m", + "isDeleted": false, + "id": "S7IJ0USPv5fLlngY-LaVx", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5037.349960327148, + "y": 2061.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 154.69992065429688, + "height": 37.800000000000004, + "seed": 82814345, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Redis Cache", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "5iwdo2T6Mu66eQsc-oiKh", + "originalText": "Redis Cache", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3471, + "versionNonce": 858614665, + "index": "b4n", + "isDeleted": false, + "id": "mWIfaHFpr0f760OCCKZrR", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5520, + "y": 2020, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 340, + "height": 120.00000000000001, + "seed": 1202702727, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "T6fBop9DsXvZMhEEM0Egm", + "type": "text" + }, + { + "id": "Gv2BWIk7nqshrAH-SZMgP", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3604, + "versionNonce": 862524009, + "index": "b4o", + "isDeleted": false, + "id": "T6fBop9DsXvZMhEEM0Egm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5436.099952697754, + "y": 2061.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 172.1999053955078, + "height": 37.800000000000004, + "seed": 1848311975, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "External APIs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "mWIfaHFpr0f760OCCKZrR", + "originalText": "External APIs", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3488, + "versionNonce": 1062001993, + "index": "b4p", + "isDeleted": false, + "id": "txjsmBg-ZTHSqz2Q50Y6g", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5020, + "y": 2300, + "strokeColor": "#ffffff", + "backgroundColor": "#4dabf7", + "width": 360, + "height": 120.00000000000001, + "seed": 804098247, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "t1tAKFBR6sVlMU9TNPW4A", + "type": "text" + }, + { + "id": "q2iIJGHtHT7Md9495pafs", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3619, + "versionNonce": 1983138857, + "index": "b4q", + "isDeleted": false, + "id": "t1tAKFBR6sVlMU9TNPW4A", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4915.935966491699, + "y": 2341.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 151.87193298339844, + "height": 37.800000000000004, + "seed": 1907220455, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "PostgreSQL", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "txjsmBg-ZTHSqz2Q50Y6g", + "originalText": "PostgreSQL", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3494, + "versionNonce": 712457, + "index": "b4r", + "isDeleted": false, + "id": "eyWPvF_lYPerHAWzUmWtg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4560, + "y": 2300, + "strokeColor": "#ffffff", + "backgroundColor": "#4dabf7", + "width": 360, + "height": 120.00000000000001, + "seed": 119743911, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "OkGpWT5bSFSuyn_YYJgIE", + "type": "text" + }, + { + "id": "ci02u6TnIX8wdAMVyYKcY", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3645, + "versionNonce": 2068583913, + "index": "b4s", + "isDeleted": false, + "id": "OkGpWT5bSFSuyn_YYJgIE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4470.8459548950195, + "y": 2341.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 181.69190979003906, + "height": 37.800000000000004, + "seed": 2065553607, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Storage", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "eyWPvF_lYPerHAWzUmWtg", + "originalText": "Cloud Storage", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 4281, + "versionNonce": 721645769, + "index": "b4t", + "isDeleted": false, + "id": "omsbCzGayEZl4x84LngPg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4420.1, + "y": 1026, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 639.9, + "height": 188, + "seed": 1946363783, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "YEVPMPsYYw1DMt-h6LSk1", + "mode": "orbit", + "fixedPoint": [ + 0.8260869565217391, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 34 + ], + [ + -639.9, + 34 + ], + [ + -639.9, + 188 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 34 + ], + "end": [ + -639.9, + 34 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4014, + "versionNonce": 1869032713, + "index": "b4w", + "isDeleted": false, + "id": "uYetgu6N8TOvRgyJCzGLH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5300.1, + "y": 1026, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 90, + "height": 188, + "seed": 1957554471, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569982, + "link": null, + "locked": false, + "startBinding": { + "elementId": "JQk-e3Od1od66GryemVE0", + "mode": "orbit", + "fixedPoint": [ + 0.49964285714285717, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "YEVPMPsYYw1DMt-h6LSk1", + "mode": "orbit", + "fixedPoint": [ + 0.49978260869565216, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 14 + ], + [ + 90, + 14 + ], + [ + 90, + 188 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 14 + ], + "end": [ + 90, + 14 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5454, + "versionNonce": 1053987465, + "index": "b4x", + "isDeleted": false, + "id": "W0WAvpfTEAOhN67ZBU1v-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4974.720966106174, + "y": 1240.8937388098734, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 229.5510704684391, + "height": 0.6147068761097216, + "seed": 504187175, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "YEVPMPsYYw1DMt-h6LSk1", + "mode": "orbit", + "fixedPoint": [ + 0.8239632464195095, + 0.1760367535804865 + ] + }, + "endBinding": { + "elementId": "b008uK7WcSm53NPiSaBMi", + "mode": "orbit", + "fixedPoint": [ + 0.16715243132931681, + 0.16715243132931806 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 229.5510704684391, + -0.6147068761097216 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 3421, + "versionNonce": 2110871913, + "index": "b52", + "isDeleted": false, + "id": "A3VSFz4rLUMsv9tHS0_cs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5440, + "y": 1380, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 460, + "height": 120.00000000000001, + "seed": 146551559, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "0TEcmVJJDp8Qrns4C0djq", + "type": "text" + }, + { + "id": "rspg9J1pILn8IK31qMo9V", + "type": "arrow" + }, + { + "id": "Qo_vDm6mdU7PyJFlqIwSW", + "type": "arrow" + } + ], + "updated": 1774013569608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3578, + "versionNonce": 1125401673, + "index": "b53", + "isDeleted": false, + "id": "0TEcmVJJDp8Qrns4C0djq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5332.849937438965, + "y": 1402.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 245.6998748779297, + "height": 75.60000000000001, + "seed": 1961769511, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "REST Controllers /\nGraphQL Resolvers", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "A3VSFz4rLUMsv9tHS0_cs", + "originalText": "REST Controllers /\nGraphQL Resolvers", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5584, + "versionNonce": 2054607657, + "index": "b54", + "isDeleted": false, + "id": "Qo_vDm6mdU7PyJFlqIwSW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4974, + "y": 1440.012, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 227.99999999999994, + "height": 2.2737367544323206e-13, + "seed": 307911623, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "A3VSFz4rLUMsv9tHS0_cs", + "mode": "orbit", + "fixedPoint": [ + 1, + 0.5001 + ] + }, + "endBinding": { + "elementId": "NPcgzotrcXnsjzhddi0G3", + "mode": "orbit", + "fixedPoint": [ + 0, + 0.5001 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 227.99999999999994, + -2.2737367544323206e-13 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 6203, + "versionNonce": 140805641, + "index": "b55", + "isDeleted": false, + "id": "86nTXYTzYBBsCXUq5vu-z", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4509.954, + "y": 1506, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0, + "height": 28, + "seed": 259572487, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "NPcgzotrcXnsjzhddi0G3", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "ibVvxd27TveKHay4jeOEi", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 28 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 4554, + "versionNonce": 936959209, + "index": "b56", + "isDeleted": false, + "id": "rspg9J1pILn8IK31qMo9V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4746, + "y": 1300, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 464.1, + "height": 74, + "seed": 1461725511, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "b008uK7WcSm53NPiSaBMi", + "mode": "orbit", + "fixedPoint": [ + -0.013043478260869565, + 0.6666666666666666 + ] + }, + "endBinding": { + "elementId": "A3VSFz4rLUMsv9tHS0_cs", + "mode": "orbit", + "fixedPoint": [ + 0.4997826086956521, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -154, + 0 + ], + [ + -154, + 60 + ], + [ + -464.1, + 60 + ], + [ + -464.1, + 74 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -154, + 0 + ], + "end": [ + -154, + 60 + ] + }, + { + "index": 3, + "start": [ + -154, + 60 + ], + "end": [ + -464.1, + 60 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 6650, + "versionNonce": 1751078857, + "index": "b57", + "isDeleted": false, + "id": "vjQKFEiN2SdKX_ffoHoeI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4510.007900276835, + "y": 1666, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.48752055726515664, + "height": 54.26917105682537, + "seed": 1530535561, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ibVvxd27TveKHay4jeOEi", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "BhVJJ5nBZINfY5FZQ7wXT", + "mode": "inside", + "fixedPoint": [ + 0.46720180989343624, + 0.0022430921402114257 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.48752055726515664, + 54.26917105682537 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 4702, + "versionNonce": 2081650345, + "index": "b58", + "isDeleted": false, + "id": "Gv2BWIk7nqshrAH-SZMgP", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4700, + "y": 1666, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 650.1, + "height": 348, + "seed": 1626598471, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ibVvxd27TveKHay4jeOEi", + "mode": "orbit", + "fixedPoint": [ + 0.08695652173913043, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "mWIfaHFpr0f760OCCKZrR", + "mode": "orbit", + "fixedPoint": [ + 0.4997058823529411, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 8 + ], + [ + -650.1, + 8 + ], + [ + -650.1, + 348 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 8 + ], + "end": [ + -650.1, + 8 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4848, + "versionNonce": 94419337, + "index": "b59", + "isDeleted": false, + "id": "l0z1zPuhs6p8ZTiIZcSEo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4640, + "y": 1666, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 420, + "height": 348, + "seed": 89138855, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ibVvxd27TveKHay4jeOEi", + "mode": "orbit", + "fixedPoint": [ + 0.21739130434782608, + 1.0499999999999998 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 22 + ], + [ + -420, + 22 + ], + [ + -420, + 348 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 22 + ], + "end": [ + -420, + 22 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5027, + "versionNonce": 910336105, + "index": "b5A", + "isDeleted": false, + "id": "WoACknI0HVTCC-IAmWk4K", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4580, + "y": 1666, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 120, + "height": 348, + "seed": 1469993063, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "xIn0URm3b-fP982jJYyCL", + "mode": "orbit", + "fixedPoint": [ + 0.1111111111111111, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 34 + ], + [ + -120, + 34 + ], + [ + -120, + 348 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 34 + ], + "end": [ + -120, + 34 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4284, + "versionNonce": 197438281, + "index": "b5C", + "isDeleted": false, + "id": "ci02u6TnIX8wdAMVyYKcY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4440, + "y": 1666, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 180, + "height": 628, + "seed": 184425, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "eyWPvF_lYPerHAWzUmWtg", + "mode": "orbit", + "fixedPoint": [ + 0.8333333333333334, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 14 + ], + [ + 180, + 14 + ], + [ + 180, + 628 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 14 + ], + "end": [ + 180, + 14 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5481, + "versionNonce": 1048730153, + "index": "b5D", + "isDeleted": false, + "id": "q2iIJGHtHT7Md9495pafs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -4560.1, + "y": 2146, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 259.9, + "height": 148, + "seed": 1380356775, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774013569608, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "txjsmBg-ZTHSqz2Q50Y6g", + "mode": "orbit", + "fixedPoint": [ + 0.5555555555555556, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 28 + ], + [ + -259.9, + 28 + ], + [ + -259.9, + 148 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 28 + ], + "end": [ + -259.9, + 28 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 3530, + "versionNonce": 1113121513, + "index": "b5f", + "isDeleted": false, + "id": "VAH3ZusB-eFlpvV3RJqZa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1020, + "strokeColor": "#ffffff", + "backgroundColor": "#a18072", + "width": 280, + "height": 100.00000000000001, + "seed": 1613767209, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "vWJy-MCzbwZ3SXwm3KRI5", + "type": "text" + }, + { + "id": "bLcNEdYaTgiFe2DSt05OU", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3665, + "versionNonce": 1894686153, + "index": "b5g", + "isDeleted": false, + "id": "vWJy-MCzbwZ3SXwm3KRI5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7388.975929260254, + "y": 1051.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 217.9518585205078, + "height": 37.800000000000004, + "seed": 672920841, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Incoming request", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "VAH3ZusB-eFlpvV3RJqZa", + "originalText": "Incoming request", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3548, + "versionNonce": 2127166633, + "index": "b5j", + "isDeleted": false, + "id": "hmcXJXSpIvCVFcDfx36DV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1160, + "strokeColor": "#ffffff", + "backgroundColor": "#228be6", + "width": 280, + "height": 100.00000000000001, + "seed": 2061694121, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "hoKD9E0rapLAms1Az6iZU", + "type": "text" + }, + { + "id": "bLcNEdYaTgiFe2DSt05OU", + "type": "arrow" + }, + { + "id": "8NSSHiqfoLHb_NoAmqJ_O", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3689, + "versionNonce": 999718793, + "index": "b5k", + "isDeleted": false, + "id": "hoKD9E0rapLAms1Az6iZU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7354.913955688477, + "y": 1191.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 149.82791137695312, + "height": 37.800000000000004, + "seed": 969963401, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Middleware", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "hmcXJXSpIvCVFcDfx36DV", + "originalText": "Middleware", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3551, + "versionNonce": 1972348521, + "index": "b5l", + "isDeleted": false, + "id": "G4ZEBDT0_xdFc12IBhMNE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1300, + "strokeColor": "#ffffff", + "backgroundColor": "#228be6", + "width": 280, + "height": 100.00000000000001, + "seed": 1925480167, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "Dr53An-dVZ9v-odclO_1V", + "type": "text" + }, + { + "id": "8NSSHiqfoLHb_NoAmqJ_O", + "type": "arrow" + }, + { + "id": "WJUkMfcyf5zHuTSBsGfEZ", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3717, + "versionNonce": 662761801, + "index": "b5m", + "isDeleted": false, + "id": "Dr53An-dVZ9v-odclO_1V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7363.901954650879, + "y": 1312.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 167.8039093017578, + "height": 75.60000000000001, + "seed": 868354567, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Guards\nAuth & Roles", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "G4ZEBDT0_xdFc12IBhMNE", + "originalText": "Guards\nAuth & Roles", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3570, + "versionNonce": 1724244009, + "index": "b5n", + "isDeleted": false, + "id": "APMYwSHAqw4B96u0BkSuX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1440, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 100.00000000000001, + "seed": 1459528007, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "z8vdyHEsUgWoARcA2xull", + "type": "text" + }, + { + "id": "WJUkMfcyf5zHuTSBsGfEZ", + "type": "arrow" + }, + { + "id": "qXj5XsbC0GwKVJQvxeeRD", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3768, + "versionNonce": 290059017, + "index": "b5o", + "isDeleted": false, + "id": "z8vdyHEsUgWoARcA2xull", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7375.437934875488, + "y": 1452.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 190.87586975097656, + "height": 75.60000000000001, + "seed": 625533031, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Interceptors\nPre-processing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "APMYwSHAqw4B96u0BkSuX", + "originalText": "Interceptors\nPre-processing", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3588, + "versionNonce": 998812137, + "index": "b5p", + "isDeleted": false, + "id": "jGzOkNVhuGxOP86OlNIhw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1580, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 100.00000000000001, + "seed": 1809611177, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "RGWRNfYAcRJKqjxCpBB2P", + "type": "text" + }, + { + "id": "qXj5XsbC0GwKVJQvxeeRD", + "type": "arrow" + }, + { + "id": "mgPDoEWpElIq88MURhON8", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3806, + "versionNonce": 1586332873, + "index": "b5q", + "isDeleted": false, + "id": "RGWRNfYAcRJKqjxCpBB2P", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7343.867958068848, + "y": 1592.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 127.73591613769531, + "height": 75.60000000000001, + "seed": 995187849, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Pipes\nValidation", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jGzOkNVhuGxOP86OlNIhw", + "originalText": "Pipes\nValidation", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3603, + "versionNonce": 1173619625, + "index": "b5t", + "isDeleted": false, + "id": "1evtk_6y2VF611gM2NOBo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1740, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 100.00000000000001, + "seed": 588316007, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "DPcVGYyArpr_U8yEKGf-Q", + "type": "text" + }, + { + "id": "mgPDoEWpElIq88MURhON8", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3861, + "versionNonce": 1038591625, + "index": "b5u", + "isDeleted": false, + "id": "DPcVGYyArpr_U8yEKGf-Q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7410.087921142578, + "y": 1752.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 260.17584228515625, + "height": 75.60000000000001, + "seed": 1392162951, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Controller / Resolver\nRoute Handler", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1evtk_6y2VF611gM2NOBo", + "originalText": "Controller / Resolver\nRoute Handler", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3612, + "versionNonce": 19131753, + "index": "b5v", + "isDeleted": false, + "id": "r_aQXLjOcUY3O_WLCpL_K", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 1900, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 100.00000000000001, + "seed": 1944433929, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "80ofMsPjE71LVSfPD4Jh7", + "type": "text" + }, + { + "id": "AfWPQ3-3csV_KeVX0743Q", + "type": "arrow" + }, + { + "id": "IAYP1x3s1ry_c5FyXZwr5", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3857, + "versionNonce": 1727289417, + "index": "b5w", + "isDeleted": false, + "id": "80ofMsPjE71LVSfPD4Jh7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7373.687934875488, + "y": 1912.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 187.37586975097656, + "height": 75.60000000000001, + "seed": 425470953, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Service\nBusiness Logic", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "r_aQXLjOcUY3O_WLCpL_K", + "originalText": "Service\nBusiness Logic", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3627, + "versionNonce": 1362388777, + "index": "b5x", + "isDeleted": false, + "id": "4EfK7iJz7NHeiNRgzexL5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7420, + "y": 2040, + "strokeColor": "#ffffff", + "backgroundColor": "#38d9a9", + "width": 280, + "height": 100.00000000000001, + "seed": 1257867719, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "iC3ePoQsnfnS-5L4As7HD", + "type": "text" + }, + { + "id": "IAYP1x3s1ry_c5FyXZwr5", + "type": "arrow" + }, + { + "id": "34SMaY8rGljt__iTBf4ED", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3919, + "versionNonce": 1515166217, + "index": "b5y", + "isDeleted": false, + "id": "iC3ePoQsnfnS-5L4As7HD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7382.017929077148, + "y": 2052.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 204.03585815429688, + "height": 75.60000000000001, + "seed": 450017511, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Interceptors\nPost-processing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4EfK7iJz7NHeiNRgzexL5", + "originalText": "Interceptors\nPost-processing", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3683, + "versionNonce": 1128362217, + "index": "b62", + "isDeleted": false, + "id": "gx-A5OpMC-Ine4OFKbJ8j", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7520, + "y": 2400, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 200, + "height": 60.000000000000014, + "seed": 1513206473, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "x4X_ZjCivwyeMyRe4QDr7", + "type": "text" + }, + { + "id": "lnFy8895Pj3FPNO9WMXr9", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3991, + "versionNonce": 563440585, + "index": "b63", + "isDeleted": false, + "id": "x4X_ZjCivwyeMyRe4QDr7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7481.795967102051, + "y": 2411.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 123.59193420410156, + "height": 37.800000000000004, + "seed": 1491235241, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Response", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "gx-A5OpMC-Ine4OFKbJ8j", + "originalText": "Response", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3705, + "versionNonce": 1298598569, + "index": "b64", + "isDeleted": false, + "id": "krlFnwc75aOTzD5xQDg7_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7240, + "y": 2400, + "strokeColor": "#ffffff", + "backgroundColor": "#fc1d32", + "width": 200, + "height": 60, + "seed": 2079801127, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "WBYbCvSRaC7tJq-lLk6j0", + "type": "text" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4031, + "versionNonce": 258067849, + "index": "b65", + "isDeleted": false, + "id": "WBYbCvSRaC7tJq-lLk6j0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7234.975936889648, + "y": 2411.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 189.95187377929688, + "height": 37.800000000000004, + "seed": 1093845575, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Exception filter", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "krlFnwc75aOTzD5xQDg7_", + "originalText": "Exception filter", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 4979, + "versionNonce": 247542889, + "index": "b68", + "isDeleted": false, + "id": "bLcNEdYaTgiFe2DSt05OU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7279.992007330834, + "y": 1126, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.11943857856726936, + "height": 35.81844461642834, + "seed": 672779911, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "VAH3ZusB-eFlpvV3RJqZa", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "hmcXJXSpIvCVFcDfx36DV", + "mode": "inside", + "fixedPoint": [ + 0.49960197889499514, + 0.018184446164283368 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.11943857856726936, + 35.81844461642834 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5281, + "versionNonce": 2135998281, + "index": "b69", + "isDeleted": false, + "id": "8NSSHiqfoLHb_NoAmqJ_O", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7279.785160677468, + "y": 1266, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1.0758294327982298, + "height": 34.54827661188483, + "seed": 320129257, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "hmcXJXSpIvCVFcDfx36DV", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "G4ZEBDT0_xdFc12IBhMNE", + "mode": "inside", + "fixedPoint": [ + 0.5046095312690344, + 0.00548276611884944 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 1.0758294327982298, + 34.54827661188483 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5412, + "versionNonce": 258731561, + "index": "b6A", + "isDeleted": false, + "id": "WJUkMfcyf5zHuTSBsGfEZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7279.926364906299, + "y": 1406, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.26103146370036256, + "height": 34.31983272458365, + "seed": 781083401, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "G4ZEBDT0_xdFc12IBhMNE", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "APMYwSHAqw4B96u0BkSuX", + "mode": "inside", + "fixedPoint": [ + 0.5011952377050063, + 0.0031983272458364805 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.26103146370036256, + 34.31983272458365 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5545, + "versionNonce": 368984329, + "index": "b6D", + "isDeleted": false, + "id": "qXj5XsbC0GwKVJQvxeeRD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7280.052648612563, + "y": 1546, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.48263631013605846, + "height": 35.906604823093176, + "seed": 1584874471, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "APMYwSHAqw4B96u0BkSuX", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "jGzOkNVhuGxOP86OlNIhw", + "mode": "inside", + "fixedPoint": [ + 0.498088268133219, + 0.01906604823093175 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.48263631013605846, + 35.906604823093176 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5501, + "versionNonce": 8599529, + "index": "b6F", + "isDeleted": false, + "id": "mgPDoEWpElIq88MURhON8", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7279.972, + "y": 1686, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0, + "height": 54.68201622281981, + "seed": 931170505, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "jGzOkNVhuGxOP86OlNIhw", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "1evtk_6y2VF611gM2NOBo", + "mode": "inside", + "fixedPoint": [ + 0.5001, + 0.0068201622281981135 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 54.68201622281981 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5731, + "versionNonce": 17191625, + "index": "b6G", + "isDeleted": false, + "id": "AfWPQ3-3csV_KeVX0743Q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7280, + "y": 1840, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.025199999999983902, + "height": 54, + "seed": 854383529, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "r_aQXLjOcUY3O_WLCpL_K", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.025199999999983902, + 54 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5955, + "versionNonce": 2082673065, + "index": "b6H", + "isDeleted": false, + "id": "IAYP1x3s1ry_c5FyXZwr5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7279.972, + "y": 2006.0000000000002, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0, + "height": 34.01424427812822, + "seed": 1198917223, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "r_aQXLjOcUY3O_WLCpL_K", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "4EfK7iJz7NHeiNRgzexL5", + "mode": "inside", + "fixedPoint": [ + 0.5001, + 0.00014244278128444418 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 34.01424427812822 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 6229, + "versionNonce": 923071625, + "index": "b6I", + "isDeleted": false, + "id": "34SMaY8rGljt__iTBf4ED", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7278.81964183049, + "y": 2139.216456426644, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.173460756847021, + "height": 47.51892627275606, + "seed": 943548777, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "4EfK7iJz7NHeiNRgzexL5", + "mode": "inside", + "fixedPoint": [ + 0.5042155648911093, + 0.9921645642664428 + ] + }, + "endBinding": { + "elementId": "fThnf5UfNjTw8DsK0e2eP", + "mode": "inside", + "fixedPoint": [ + 0.5061537223925346, + 0.03200698390210915 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.173460756847021, + 47.51892627275606 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3249, + "versionNonce": 1164409705, + "index": "b6J", + "isDeleted": false, + "id": "lnFy8895Pj3FPNO9WMXr9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7332.703814743127, + "y": 2300.564425020001, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 89.9828537885914, + "height": 99.57853807235051, + "seed": 544268167, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "bdaVvT6u8-CJjPRHXt8xk" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false, + "startBinding": { + "elementId": "7SpEkwk42r9BzlqGc6abS", + "mode": "inside", + "fixedPoint": [ + 0.3353005789277283, + 0.8732692862857415 + ] + }, + "endBinding": { + "elementId": "gx-A5OpMC-Ine4OFKbJ8j", + "mode": "inside", + "fixedPoint": [ + 0.4865666573414083, + 0.002382718205857751 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -67.29618525687306, + 39.435574979999046 + ], + [ + -89.9828537885914, + 99.57853807235051 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 51, + "versionNonce": 104644455, + "index": "b6K", + "isDeleted": false, + "id": "bdaVvT6u8-CJjPRHXt8xk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -399.1386079590925, + "y": 1915.1615042011786, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 50.84797668457031, + "height": 37.800000000000004, + "seed": 2052675239, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774014966456, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "YES", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lnFy8895Pj3FPNO9WMXr9", + "originalText": "YES", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "fThnf5UfNjTw8DsK0e2eP", + "type": "diamond", + "x": -7390, + "y": 2180, + "width": 220, + "height": 210.43478260869568, + "angle": 0, + "strokeColor": "#ff5f00", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6KG", + "roundness": { + "type": 2 + }, + "seed": 547073449, + "version": 588, + "versionNonce": 932587081, + "isDeleted": false, + "boundElements": [ + { + "id": "34SMaY8rGljt__iTBf4ED", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false + }, + { + "id": "7SpEkwk42r9BzlqGc6abS", + "type": "text", + "x": -7440, + "y": 2270, + "width": 320, + "height": 35, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6L", + "roundness": null, + "seed": 1806688807, + "version": 514, + "versionNonce": 141325609, + "isDeleted": false, + "boundElements": [ + { + "id": "lnFy8895Pj3FPNO9WMXr9", + "type": "arrow" + } + ], + "updated": 1774015237816, + "link": null, + "locked": false, + "text": "Exception?", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Exception?", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "GjPfgU9ahbsQgX87NfaWu", + "type": "ellipse", + "x": -845, + "y": 855, + "width": 40, + "height": 40, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "nsJN_sM0Rb9mrGU4Pwwke" + ], + "frameId": null, + "index": "b6M", + "roundness": null, + "seed": 2047278471, + "version": 86, + "versionNonce": 603507902, + "isDeleted": true, + "boundElements": [], + "updated": 1774254409833, + "link": null, + "locked": false + }, + { + "id": "_XD7wm14zS5JDQP03c33R", + "type": "line", + "x": -825, + "y": 880, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "nsJN_sM0Rb9mrGU4Pwwke" + ], + "frameId": null, + "index": "b6N", + "roundness": null, + "seed": 1167023527, + "version": 80, + "versionNonce": 1314252322, + "isDeleted": true, + "boundElements": [], + "updated": 1774254409833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 40 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "ZeD1rgZo2n-jIW0yA-C_L", + "type": "line", + "x": -845, + "y": 900, + "width": 40, + "height": 0, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "nsJN_sM0Rb9mrGU4Pwwke" + ], + "frameId": null, + "index": "b6O", + "roundness": null, + "seed": 1608642535, + "version": 102, + "versionNonce": 1459389694, + "isDeleted": true, + "boundElements": [], + "updated": 1774254409833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "EKYQWAP7xLZDXGHJZdqnr", + "type": "line", + "x": -845, + "y": 940, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "nsJN_sM0Rb9mrGU4Pwwke" + ], + "frameId": null, + "index": "b6P", + "roundness": null, + "seed": 1595739945, + "version": 107, + "versionNonce": 146330082, + "isDeleted": true, + "boundElements": [], + "updated": 1774254409833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "7wTsvd7logQUpVOxuSMLh", + "type": "line", + "x": -805, + "y": 940, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "nsJN_sM0Rb9mrGU4Pwwke" + ], + "frameId": null, + "index": "b6Q", + "roundness": null, + "seed": 741119529, + "version": 111, + "versionNonce": 425669950, + "isDeleted": true, + "boundElements": [], + "updated": 1774254409833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "uyvAqvyJPm81RxkOh2W4I", + "type": "ellipse", + "x": -845, + "y": 1160, + "width": 40, + "height": 40, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "-5iHhlymNHEhfdFcYVqWi" + ], + "frameId": null, + "index": "b6R", + "roundness": null, + "seed": 602007623, + "version": 81, + "versionNonce": 1458679486, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411993, + "link": null, + "locked": false + }, + { + "id": "6ylbK97DyPLIaRh80-EuA", + "type": "line", + "x": -825, + "y": 1185, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "-5iHhlymNHEhfdFcYVqWi" + ], + "frameId": null, + "index": "b6S", + "roundness": null, + "seed": 606816103, + "version": 75, + "versionNonce": 223618082, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411993, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 40 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "NdylXfHG2fuwiA2JMK4g4", + "type": "line", + "x": -845, + "y": 1205, + "width": 40, + "height": 0, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "-5iHhlymNHEhfdFcYVqWi" + ], + "frameId": null, + "index": "b6T", + "roundness": null, + "seed": 238797447, + "version": 97, + "versionNonce": 1015621374, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411993, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "bm7twOhR9i8Pk75Q6mRPG", + "type": "line", + "x": -845, + "y": 1245, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "-5iHhlymNHEhfdFcYVqWi" + ], + "frameId": null, + "index": "b6U", + "roundness": null, + "seed": 1389353383, + "version": 102, + "versionNonce": 155144162, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411993, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "7S5X55hIdyTLANIsw3JaB", + "type": "line", + "x": -805, + "y": 1245, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "-5iHhlymNHEhfdFcYVqWi" + ], + "frameId": null, + "index": "b6V", + "roundness": null, + "seed": 387189959, + "version": 106, + "versionNonce": 688363326, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411993, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "type": "rectangle", + "version": 1157, + "versionNonce": 467462206, + "index": "b6W", + "isDeleted": false, + "id": "lcJ9L3mIzWblAj2k0sgxo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6220, + "y": 2780, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 630599751, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jTZ-fcXThOteoJwQA5S7V" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "jTZ-fcXThOteoJwQA5S7V", + "type": "text", + "x": -6155.939964294434, + "y": 2807.5, + "width": 71.87992858886719, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6W8", + "roundness": null, + "seed": 1975257255, + "version": 123, + "versionNonce": 47263870, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Our API", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lcJ9L3mIzWblAj2k0sgxo", + "originalText": "Our API", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1209, + "versionNonce": 1284665534, + "index": "b6Y", + "isDeleted": false, + "id": "0Bz-sB_Ks3yswxYs-vPHm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6560, + "y": 2780, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 900070697, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jQg2GfyTSTy9XI3lqydV3" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "jQg2GfyTSTy9XI3lqydV3", + "type": "text", + "x": -6500.769958496094, + "y": 2807.5, + "width": 81.5399169921875, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6Z", + "roundness": null, + "seed": 673083401, + "version": 210, + "versionNonce": 79800574, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Frontend", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0Bz-sB_Ks3yswxYs-vPHm", + "originalText": "Frontend", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1216, + "versionNonce": 450877758, + "index": "b6a", + "isDeleted": false, + "id": "QiI4qhuqcD4DZu1KI7l_S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5740, + "y": 2780, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 624101447, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "871lcLGI0D48Ov5poEiEG" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "871lcLGI0D48Ov5poEiEG", + "type": "text", + "x": -5666.9599685668945, + "y": 2807.5, + "width": 53.91993713378906, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6b", + "roundness": null, + "seed": 509110119, + "version": 195, + "versionNonce": 1716388222, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Stripe", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QiI4qhuqcD4DZu1KI7l_S", + "originalText": "Stripe", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1205, + "versionNonce": 709697982, + "index": "b6c", + "isDeleted": false, + "id": "yt8vaRUJSvcbIVM2nmpjT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6220, + "y": 3640, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 98908009, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "mey65lsjY64CLntyJqPmm" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "mey65lsjY64CLntyJqPmm", + "type": "text", + "x": -6155.939964294434, + "y": 3667.5, + "width": 71.87992858886719, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6d", + "roundness": null, + "seed": 419193417, + "version": 158, + "versionNonce": 436091390, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Our API", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yt8vaRUJSvcbIVM2nmpjT", + "originalText": "Our API", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1260, + "versionNonce": 1549945406, + "index": "b6e", + "isDeleted": false, + "id": "s_JI1593iq_hJg_R_1IvF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6560, + "y": 3640, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1303783943, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "rFN-tqOZ0B7ofawNfxju5" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "rFN-tqOZ0B7ofawNfxju5", + "type": "text", + "x": -6500.769958496094, + "y": 3667.5, + "width": 81.5399169921875, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6f", + "roundness": null, + "seed": 361845031, + "version": 234, + "versionNonce": 274354814, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Frontend", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s_JI1593iq_hJg_R_1IvF", + "originalText": "Frontend", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1258, + "versionNonce": 1353142974, + "index": "b6g", + "isDeleted": false, + "id": "zkZaS-kk9pWzcCbzcuZRQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5740, + "y": 3640, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1258133255, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "82OdQkvTkP5NZWrKTnnRY" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "82OdQkvTkP5NZWrKTnnRY", + "type": "text", + "x": -5666.9599685668945, + "y": 3667.5, + "width": 53.91993713378906, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6h", + "roundness": null, + "seed": 828579367, + "version": 217, + "versionNonce": 938101502, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Stripe", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "zkZaS-kk9pWzcCbzcuZRQ", + "originalText": "Stripe", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "DcAPa8YVbK2YYramoE_S5", + "type": "line", + "x": -825, + "y": 960, + "width": 0, + "height": 180, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6i", + "roundness": null, + "seed": 992411847, + "version": 42, + "versionNonce": 449799330, + "isDeleted": true, + "boundElements": [], + "updated": 1774254411034, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 180 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "VeN4GCcRRdsshmX7DcGeJ", + "type": "line", + "x": -6120, + "y": 2860, + "width": 0, + "height": 780, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6j", + "roundness": null, + "seed": 807603689, + "version": 145, + "versionNonce": 1688484670, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 780 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "Zy_oFAreiS6g0a5Lq0pCd", + "type": "line", + "x": -6460, + "y": 2860, + "width": 0, + "height": 780, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6k", + "roundness": null, + "seed": 80515207, + "version": 180, + "versionNonce": 2100700030, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 780 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "y9wF1rTId1DhjrZSPruXB", + "type": "line", + "x": -5640, + "y": 2860, + "width": 0, + "height": 780, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6l", + "roundness": null, + "seed": 853046409, + "version": 215, + "versionNonce": 870384574, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 780 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "type": "text", + "version": 1193, + "versionNonce": 971707902, + "index": "b6m", + "isDeleted": true, + "id": "Dx4RP4PtZ4ga3xg_4ROAE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -840, + "y": 940, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 33.8079833984375, + "height": 21.6, + "seed": 1309135849, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254410474, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "User", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "User", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1212, + "versionNonce": 1722957666, + "index": "b6n", + "isDeleted": true, + "id": "LxEenBojOuH54V9nedP7q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -842, + "y": 1245, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 33.8079833984375, + "height": 21.6, + "seed": 894717801, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254412689, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "User", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "User", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "3fvPtMCljkBbXSOhfMzjj", + "type": "rectangle", + "x": -6125, + "y": 2900, + "width": 10, + "height": 240, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6o", + "roundness": null, + "seed": 1240951657, + "version": 124, + "versionNonce": 1254480894, + "isDeleted": false, + "boundElements": [ + { + "id": "557ztgLiAqSgnu_8dXxKp", + "type": "arrow" + }, + { + "id": "W847jFZWWvyZsRNgmCD_P", + "type": "arrow" + }, + { + "id": "yImHSWv7AMzzRwje6QWcX", + "type": "arrow" + }, + { + "id": "0K771ra8wwTZvkTIE8ecn", + "type": "arrow" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "WmPGEQfQvj_EPYa2bQZ9n", + "type": "rectangle", + "x": -365, + "y": 1000, + "width": 10, + "height": 100, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6p", + "roundness": null, + "seed": 1823334089, + "version": 59, + "versionNonce": 292540094, + "isDeleted": true, + "boundElements": [ + { + "id": "0K771ra8wwTZvkTIE8ecn", + "type": "arrow" + }, + { + "id": "yImHSWv7AMzzRwje6QWcX", + "type": "arrow" + } + ], + "updated": 1774254441371, + "link": null, + "locked": false + }, + { + "id": "hNkJoo-MgyNNbDK1vKqX9", + "type": "rectangle", + "x": -5645, + "y": 3000, + "width": 10, + "height": 60, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b6q", + "roundness": null, + "seed": 573896073, + "version": 177, + "versionNonce": 400927806, + "isDeleted": false, + "boundElements": [ + { + "id": "yImHSWv7AMzzRwje6QWcX", + "type": "arrow" + }, + { + "id": "0K771ra8wwTZvkTIE8ecn", + "type": "arrow" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 2423, + "versionNonce": 153187454, + "index": "b6r", + "isDeleted": false, + "id": "557ztgLiAqSgnu_8dXxKp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6460, + "y": 2900, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 329.00011655587946, + "height": 0.005037506026042138, + "seed": 1793187431, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 329.00011655587946, + -0.005037506026042138 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 139, + "versionNonce": 214034530, + "index": "b6s", + "isDeleted": true, + "id": "_p3_EE98_O31AKDLRmW0d", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -777.5879391585837, + "y": 969.197481246987, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 4.175994873046875, + "height": 21.6, + "seed": 268925319, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254581345, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "557ztgLiAqSgnu_8dXxKp", + "originalText": "", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2459, + "versionNonce": 854938942, + "index": "b6t", + "isDeleted": true, + "id": "YsZ_Hq-aVCEN7npVoyYHF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -589, + "y": 1000.1104727636198, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.0000913812139, + "height": 0.11179518809581168, + "seed": 1781346153, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "utyK85_8sRCINPI5R-VoD" + } + ], + "updated": 1774254440049, + "link": null, + "locked": false, + "startBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.8563281405447014, + 0.14367185945529612 + ] + }, + "endBinding": { + "elementId": "WmPGEQfQvj_EPYa2bQZ9n", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 218.0000913812139, + -0.11179518809581168 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 121, + "versionNonce": 564405666, + "index": "b6u", + "isDeleted": true, + "id": "utyK85_8sRCINPI5R-VoD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -518.3039246463071, + "y": 989.254575169572, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 76.60794067382812, + "height": 21.6, + "seed": 562387529, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254440049, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Call action", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "YsZ_Hq-aVCEN7npVoyYHF", + "originalText": "Call action", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2835, + "versionNonce": 674903230, + "index": "b6v", + "isDeleted": false, + "id": "0K771ra8wwTZvkTIE8ecn", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6109, + "y": 3000.457283273564, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 457.9999999999999, + "height": 0.4465571273669866, + "seed": 1159382217, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.5923167880269602, + 0.4186129514237317 + ] + }, + "endBinding": { + "elementId": "hNkJoo-MgyNNbDK1vKqX9", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 457.9999999999999, + -0.4465571273669866 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 145, + "versionNonce": 2102761762, + "index": "b6w", + "isDeleted": true, + "id": "SoICLtogyyn0UxXdVxWCt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -432.087930601095, + "y": 1009.1437291101187, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 4.175994873046875, + "height": 21.6, + "seed": 1759069097, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254619764, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0K771ra8wwTZvkTIE8ecn", + "originalText": "", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2897, + "versionNonce": 517008638, + "index": "b6x", + "isDeleted": false, + "id": "yImHSWv7AMzzRwje6QWcX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5650.999852386507, + "y": 3060.009783794875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 458.0001476134935, + "height": 0.25872499850402164, + "seed": 2014287785, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": { + "elementId": "hNkJoo-MgyNNbDK1vKqX9", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.6847137431712099, + 0.6678072871618582 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -458.0001476134935, + 0.25872499850402164 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 53, + "versionNonce": 1702856830, + "index": "b6y", + "isDeleted": true, + "id": "KKCecJc5vGci5CIqwHMq1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -432.08799743652344, + "y": 1069.022378288034, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 4.175994873046875, + "height": 21.6, + "seed": 1332787849, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254638099, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yImHSWv7AMzzRwje6QWcX", + "originalText": "", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2803, + "versionNonce": 95761918, + "index": "b6z", + "isDeleted": true, + "id": "U9u_H34IMquvf3DNJLEuU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -371, + "y": 1099.986610478073, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.0000000000001, + "height": 0.26533185892662914, + "seed": 796801193, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "4a4u87HmmAHwrgPP_4D-X" + } + ], + "updated": 1774254440585, + "link": null, + "locked": false, + "startBinding": { + "elementId": "WmPGEQfQvj_EPYa2bQZ9n", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.8836609423414643, + 0.8550897137364343 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -218.0000000000001, + -0.26533185892662914 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 79, + "versionNonce": 1138733282, + "index": "b70", + "isDeleted": true, + "id": "4a4u87HmmAHwrgPP_4D-X", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -530.8639602661133, + "y": 1078.25394454861, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 101.72792053222656, + "height": 43.2, + "seed": 1113799561, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254440585, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Reactive state\nupdate", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "U9u_H34IMquvf3DNJLEuU", + "originalText": "Reactive state\nupdate", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2838, + "versionNonce": 979803454, + "index": "b71", + "isDeleted": false, + "id": "W847jFZWWvyZsRNgmCD_P", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6130.99988344412, + "y": 3140.005037506028, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 329.0001165558797, + "height": 0.005037506028429561, + "seed": 7953031, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": { + "elementId": "3fvPtMCljkBbXSOhfMzjj", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -329.0001165558797, + -0.005037506028429561 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 96, + "versionNonce": 1112467362, + "index": "b72", + "isDeleted": true, + "id": "S8vsSGfXI-UiZDp0DRXEH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -777.5879391585836, + "y": 1109.2025187530146, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 4.175994873046875, + "height": 21.6, + "seed": 1503293863, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254597878, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "W847jFZWWvyZsRNgmCD_P", + "originalText": "", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "_YnAmSz0kC9odLEZOO93U", + "type": "ellipse", + "x": -7540, + "y": 2720, + "width": 40, + "height": 40, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "HuOmf2r7zVOgGtj7L5u-J" + ], + "frameId": null, + "index": "b73", + "roundness": null, + "seed": 232299810, + "version": 164, + "versionNonce": 1796627426, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "_rGTaBCzzx_JWjmBUjTgA", + "type": "line", + "x": -7520, + "y": 2745, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "HuOmf2r7zVOgGtj7L5u-J" + ], + "frameId": null, + "index": "b74", + "roundness": null, + "seed": 1422698722, + "version": 158, + "versionNonce": 694456226, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 40 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "vapMO5kb22lM4WX5zBeQp", + "type": "line", + "x": -7540, + "y": 2765, + "width": 40, + "height": 0, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "HuOmf2r7zVOgGtj7L5u-J" + ], + "frameId": null, + "index": "b75", + "roundness": null, + "seed": 13188258, + "version": 180, + "versionNonce": 792087394, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "kKdIdPXybSojFyQ-u5CBb", + "type": "line", + "x": -7540, + "y": 2805, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "HuOmf2r7zVOgGtj7L5u-J" + ], + "frameId": null, + "index": "b76", + "roundness": null, + "seed": 1870485602, + "version": 185, + "versionNonce": 1390055202, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "qUUoYgReGyZa24AT3uOaU", + "type": "line", + "x": -7500, + "y": 2805, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "HuOmf2r7zVOgGtj7L5u-J" + ], + "frameId": null, + "index": "b77", + "roundness": null, + "seed": 1891105826, + "version": 189, + "versionNonce": 1220565730, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "hbwQ08K3lliv6vY9Uf27G", + "type": "ellipse", + "x": -7540, + "y": 3025, + "width": 40, + "height": 40, + "angle": 0, + "strokeColor": "transparent", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "mrsDKh6vp8Bk_amfu_EMD" + ], + "frameId": null, + "index": "b78", + "roundness": null, + "seed": 40380386, + "version": 159, + "versionNonce": 1601613474, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "uD6okWL0kb6DwCCq8EnOY", + "type": "line", + "x": -7520, + "y": 3050, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "mrsDKh6vp8Bk_amfu_EMD" + ], + "frameId": null, + "index": "b79", + "roundness": null, + "seed": 211606434, + "version": 153, + "versionNonce": 1001163362, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 40 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "Rh_P0dzFjb-S2Q4XCa9ef", + "type": "line", + "x": -7540, + "y": 3070, + "width": 40, + "height": 0, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "mrsDKh6vp8Bk_amfu_EMD" + ], + "frameId": null, + "index": "b7A", + "roundness": null, + "seed": 495261538, + "version": 175, + "versionNonce": 338751010, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "u_VSXY0dw2K1Aevw0rkxX", + "type": "line", + "x": -7540, + "y": 3110, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "mrsDKh6vp8Bk_amfu_EMD" + ], + "frameId": null, + "index": "b7B", + "roundness": null, + "seed": 628087586, + "version": 180, + "versionNonce": 1844632034, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "PHNUBf1fabXFUiFexYeW7", + "type": "line", + "x": -7500, + "y": 3110, + "width": 20, + "height": 20, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [ + "mrsDKh6vp8Bk_amfu_EMD" + ], + "frameId": null, + "index": "b7C", + "roundness": null, + "seed": 852240098, + "version": 184, + "versionNonce": 1476480418, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -20, + -20 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "type": "rectangle", + "version": 1168, + "versionNonce": 663439714, + "index": "b7D", + "isDeleted": false, + "id": "GMg_10NJEQLXnK0hAlQO_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7395, + "y": 2725, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 774437538, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ugV3qsL7FsZg3JI3aBtiE" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "ugV3qsL7FsZg3JI3aBtiE", + "type": "text", + "x": -7367.479942321777, + "y": 2752.5, + "width": 144.9598846435547, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7E", + "roundness": null, + "seed": 372594274, + "version": 109, + "versionNonce": 870305058, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Vue Component", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "GMg_10NJEQLXnK0hAlQO_", + "originalText": "Vue Component", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1193, + "versionNonce": 309188834, + "index": "b7F", + "isDeleted": false, + "id": "is0mBao5TPAsYGoW7275a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7155, + "y": 2725, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1002453538, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "LAR8icRqreD8lrv3pvS6Q" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "LAR8icRqreD8lrv3pvS6Q", + "type": "text", + "x": -7143.729911804199, + "y": 2752.5, + "width": 177.45982360839844, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7G", + "roundness": null, + "seed": 2109253090, + "version": 158, + "versionNonce": 1388604578, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Composable / Store", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "is0mBao5TPAsYGoW7275a", + "originalText": "Composable / Store", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1213, + "versionNonce": 982681698, + "index": "b7H", + "isDeleted": false, + "id": "LuV3L_sR9owDhVl_gw9FG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6915, + "y": 2725, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 86874530, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "v82d2zboQtJiV_2c06ROD" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "v82d2zboQtJiV_2c06ROD", + "type": "text", + "x": -6872.589935302734, + "y": 2752.5, + "width": 115.17987060546875, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7I", + "roundness": null, + "seed": 21894498, + "version": 165, + "versionNonce": 27733026, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Backend API", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "LuV3L_sR9owDhVl_gw9FG", + "originalText": "Backend API", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1189, + "versionNonce": 233920482, + "index": "b7J", + "isDeleted": false, + "id": "7vDUlWeunc1YqqH3nVjRw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7395, + "y": 3025, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1667832098, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "H-c_3jV_XETcbp4HpGAYf" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "H-c_3jV_XETcbp4HpGAYf", + "type": "text", + "x": -7367.479942321777, + "y": 3052.5, + "width": 144.9598846435547, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7K", + "roundness": null, + "seed": 451781858, + "version": 130, + "versionNonce": 796920738, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Vue Component", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "7vDUlWeunc1YqqH3nVjRw", + "originalText": "Vue Component", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1212, + "versionNonce": 1552041826, + "index": "b7L", + "isDeleted": false, + "id": "KQVJplnH9uMdWU2wNC1nl", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7155, + "y": 3025, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1365948578, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "y7unFJU6CTWxKIYv__F4N" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "y7unFJU6CTWxKIYv__F4N", + "type": "text", + "x": -7143.729911804199, + "y": 3052.5, + "width": 177.45982360839844, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7M", + "roundness": null, + "seed": 646927458, + "version": 177, + "versionNonce": 1833372450, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Composable / Store", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KQVJplnH9uMdWU2wNC1nl", + "originalText": "Composable / Store", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1228, + "versionNonce": 1480414946, + "index": "b7N", + "isDeleted": false, + "id": "WaPsup7_MY6NmsIOS9Lyf", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6915, + "y": 3025, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1814722594, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "m1NyYbckomiSmPxdUcuTS" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "m1NyYbckomiSmPxdUcuTS", + "type": "text", + "x": -6872.589935302734, + "y": 3052.5, + "width": 115.17987060546875, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7O", + "roundness": null, + "seed": 1646994402, + "version": 180, + "versionNonce": 1844718242, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "text": "Backend API", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "WaPsup7_MY6NmsIOS9Lyf", + "originalText": "Backend API", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "8fHXRe32xJvsPmuApxaKp", + "type": "line", + "x": -7520, + "y": 2825, + "width": 0, + "height": 180, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7P", + "roundness": null, + "seed": 1923110818, + "version": 120, + "versionNonce": 354059874, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 180 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "5qkbZVwCR6erfvSLZAqjX", + "type": "line", + "x": -7295, + "y": 2805, + "width": 0, + "height": 220, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7Q", + "roundness": null, + "seed": 1840845666, + "version": 136, + "versionNonce": 109013538, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 220 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "oNpMImCilf8QAqnomuh36", + "type": "line", + "x": -7055, + "y": 2805, + "width": 0, + "height": 220, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7R", + "roundness": null, + "seed": 1170495266, + "version": 157, + "versionNonce": 152163810, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 220 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "50Sq9f6HUIEERhaMOktpO", + "type": "line", + "x": -6815, + "y": 2805, + "width": 0, + "height": 220, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7S", + "roundness": null, + "seed": 1261511394, + "version": 180, + "versionNonce": 769706402, + "isDeleted": false, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 220 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "type": "text", + "version": 1270, + "versionNonce": 203113826, + "index": "b7T", + "isDeleted": false, + "id": "d5q0gSed0l4LbT8gldJDA", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7537, + "y": 2805, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 33.8079833984375, + "height": 21.6, + "seed": 1754166946, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "User", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "User", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1290, + "versionNonce": 2098219298, + "index": "b7U", + "isDeleted": false, + "id": "DKM6Nvio9D4VtIbHxleJm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7537, + "y": 3110, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 33.8079833984375, + "height": 21.6, + "seed": 1586188898, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254401310, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "User", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "User", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "WaBPz455998VkLuuOl1a8", + "type": "rectangle", + "x": -7300, + "y": 2845, + "width": 10, + "height": 140, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7V", + "roundness": null, + "seed": 2146874914, + "version": 117, + "versionNonce": 1479464162, + "isDeleted": false, + "boundElements": [ + { + "id": "lfKcUaR1zkD_qMje9K4ba", + "type": "arrow" + }, + { + "id": "57xWXLvu9BEx40ov8JFeZ", + "type": "arrow" + }, + { + "id": "HwLr6Qt3JNfJP7-q7ex9v", + "type": "arrow" + }, + { + "id": "QjdX2VuapYh7Boz4pzAI-", + "type": "arrow" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "zaqfUbt6qE4ZKzwRMhKJp", + "type": "rectangle", + "x": -7060, + "y": 2865, + "width": 10, + "height": 100, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7W", + "roundness": null, + "seed": 1841275362, + "version": 135, + "versionNonce": 788916386, + "isDeleted": false, + "boundElements": [ + { + "id": "57xWXLvu9BEx40ov8JFeZ", + "type": "arrow" + }, + { + "id": "Aey1tVAhuCMigVgVo8jPW", + "type": "arrow" + }, + { + "id": "5Fg6zbSJzUNZUSCW81tX6", + "type": "arrow" + }, + { + "id": "HwLr6Qt3JNfJP7-q7ex9v", + "type": "arrow" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "id": "8L2Ep54udVzsbuDMLfH8C", + "type": "rectangle", + "x": -6820, + "y": 2885, + "width": 10, + "height": 60, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7X", + "roundness": null, + "seed": 1391793570, + "version": 152, + "versionNonce": 155485282, + "isDeleted": false, + "boundElements": [ + { + "id": "Aey1tVAhuCMigVgVo8jPW", + "type": "arrow" + }, + { + "id": "5Fg6zbSJzUNZUSCW81tX6", + "type": "arrow" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 2422, + "versionNonce": 549038114, + "index": "b7Y", + "isDeleted": false, + "id": "lfKcUaR1zkD_qMje9K4ba", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7515, + "y": 2845, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 209.00011655587946, + "height": 0.005037506026042138, + "seed": 549851490, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "xwfy5pnrTxaiFjnIWvAy-" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "WaBPz455998VkLuuOl1a8", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 209.00011655587946, + -0.005037506026042138 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 107, + "versionNonce": 1887475938, + "index": "b7Z", + "isDeleted": false, + "id": "xwfy5pnrTxaiFjnIWvAy-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1014.6838864242087, + "y": 1263.3974812469871, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 88.36788940429688, + "height": 43.2, + "seed": 1250006306, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395291, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Interaction\n(click, input)", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lfKcUaR1zkD_qMje9K4ba", + "originalText": "Interaction\n(click, input)", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2537, + "versionNonce": 492065762, + "index": "b7a", + "isDeleted": false, + "id": "57xWXLvu9BEx40ov8JFeZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7284, + "y": 2865.11047276362, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.0000913812139, + "height": 0.11179518809581168, + "seed": 26648802, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "tbNV4aUtVUKbYZ_-EKAjJ" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": { + "elementId": "WaBPz455998VkLuuOl1a8", + "mode": "orbit", + "fixedPoint": [ + 0.8563281405447014, + 0.14367185945529612 + ] + }, + "endBinding": { + "elementId": "zaqfUbt6qE4ZKzwRMhKJp", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 218.0000913812139, + -0.11179518809581168 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 124, + "versionNonce": 1618947234, + "index": "b7b", + "isDeleted": false, + "id": "tbNV4aUtVUKbYZ_-EKAjJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -773.3039246463071, + "y": 1294.254575169572, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 76.60794067382812, + "height": 21.6, + "seed": 1905538210, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395291, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Call action", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "57xWXLvu9BEx40ov8JFeZ", + "originalText": "Call action", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2604, + "versionNonce": 1361282978, + "index": "b7c", + "isDeleted": false, + "id": "Aey1tVAhuCMigVgVo8jPW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7044, + "y": 2884.877198904017, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.00014560076298, + "height": 0.1133282146821557, + "seed": 2083082338, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "I3wI1z9O3YX9MNNYwJ6sd" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": { + "elementId": "zaqfUbt6qE4ZKzwRMhKJp", + "mode": "orbit", + "fixedPoint": [ + 0.8012708425701305, + 0.19872915742985925 + ] + }, + "endBinding": { + "elementId": "8L2Ep54udVzsbuDMLfH8C", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 218.00014560076298, + 0.1133282146821557 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 146, + "versionNonce": 1123371106, + "index": "b7d", + "isDeleted": false, + "id": "I3wI1z9O3YX9MNNYwJ6sd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -556.5838581688568, + "y": 1314.133863011358, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 123.16786193847656, + "height": 21.6, + "seed": 1965356066, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395291, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "$fetch / useFetch", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Aey1tVAhuCMigVgVo8jPW", + "originalText": "$fetch / useFetch", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2661, + "versionNonce": 1951810402, + "index": "b7e", + "isDeleted": false, + "id": "5Fg6zbSJzUNZUSCW81tX6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6825.999717051164, + "y": 2945.030349092406, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.00028294883595, + "height": 0.5939383849342903, + "seed": 1584799714, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "psgyYGfa3SREVsMlnehpH" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": { + "elementId": "8L2Ep54udVzsbuDMLfH8C", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": { + "elementId": "zaqfUbt6qE4ZKzwRMhKJp", + "mode": "orbit", + "fixedPoint": [ + 0.8064592046502526, + 0.8064592046502593 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -218.00028294883595, + 0.5939383849342903 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 54, + "versionNonce": 1873931298, + "index": "b7f", + "isDeleted": false, + "id": "psgyYGfa3SREVsMlnehpH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -549.6638142140586, + "y": 1374.5273182848732, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 109.32791137695312, + "height": 21.6, + "seed": 606852002, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395291, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "JSON response", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "5Fg6zbSJzUNZUSCW81tX6", + "originalText": "JSON response", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2881, + "versionNonce": 1631291170, + "index": "b7g", + "isDeleted": false, + "id": "HwLr6Qt3JNfJP7-q7ex9v", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7066, + "y": 2964.986610478073, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 218.0000000000001, + "height": 0.26533185892662914, + "seed": 1484066658, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "iNPMGw34KOuTgEHa9-elc" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": { + "elementId": "zaqfUbt6qE4ZKzwRMhKJp", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": { + "elementId": "WaBPz455998VkLuuOl1a8", + "mode": "orbit", + "fixedPoint": [ + 0.8836609423414643, + 0.8550897137364343 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -218.0000000000001, + -0.26533185892662914 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 82, + "versionNonce": 1822693346, + "index": "b7h", + "isDeleted": false, + "id": "iNPMGw34KOuTgEHa9-elc", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -785.8639602661133, + "y": 1383.2539445486098, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 101.72792053222656, + "height": 43.2, + "seed": 1872810786, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395291, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "Reactive state\nupdate", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "HwLr6Qt3JNfJP7-q7ex9v", + "originalText": "Reactive state\nupdate", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2827, + "versionNonce": 1346523874, + "index": "b7i", + "isDeleted": false, + "id": "QjdX2VuapYh7Boz4pzAI-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7305.99988344412, + "y": 2985.0050375060287, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 209.00011655587969, + "height": 0.005037506028656935, + "seed": 2082348770, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "type": "text", + "id": "wLCLUywIzeRb9Eo4KQeaG" + } + ], + "updated": 1774254401310, + "link": null, + "locked": false, + "startBinding": { + "elementId": "WaBPz455998VkLuuOl1a8", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -209.00011655587969, + -0.005037506028656935 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "text", + "version": 97, + "versionNonce": 702204834, + "index": "b7j", + "isDeleted": false, + "id": "wLCLUywIzeRb9Eo4KQeaG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1005.8039196883688, + "y": 1414.2025187530146, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 70.60795593261719, + "height": 21.6, + "seed": 1786507938, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254395292, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 6, + "text": "UI update", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QjdX2VuapYh7Boz4pzAI-", + "originalText": "UI update", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "id": "ghz1aWUKSaJ-hy238QaEE", + "type": "text", + "x": -900, + "y": 1020, + "width": 240, + "height": 20, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7k", + "roundness": null, + "seed": 1856999294, + "version": 15, + "versionNonce": 1572000190, + "isDeleted": true, + "boundElements": null, + "updated": 1774254569221, + "link": null, + "locked": false, + "text": "", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "", + "autoResize": false, + "lineHeight": 1.25 + }, + { + "id": "6QM2yiWS3abhT-bVauWJ0", + "type": "text", + "x": -6380.176063537598, + "y": 2880, + "width": 161.47186279296875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7l", + "roundness": null, + "seed": 633469694, + "version": 105, + "versionNonce": 1885095294, + "isDeleted": false, + "boundElements": null, + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Create payment intent", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Create payment intent", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "8aLP7tzgdCW4fipJjw_ZS", + "type": "text", + "x": -897.8010751857582, + "y": 962.480783736051, + "width": 241.2797393798828, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7m", + "roundness": null, + "seed": 387070910, + "version": 3, + "versionNonce": 2092589986, + "isDeleted": true, + "boundElements": null, + "updated": 1774254602892, + "link": null, + "locked": false, + "text": "emailService.sendWelocme(user)", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "emailService.sendWelocme(user)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "ZXCyq2AVf6jY1B6ItmFup", + "type": "text", + "x": -6340, + "y": 3120, + "width": 91.47190856933594, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7n", + "roundness": null, + "seed": 1512629310, + "version": 133, + "versionNonce": 1643308478, + "isDeleted": false, + "boundElements": null, + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "client_secret", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "client_secret", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "iBU3p-xEChKiWAI-_2fLq", + "type": "text", + "x": -762.0879974365234, + "y": 1140, + "width": 4.175994873046875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7o", + "roundness": null, + "seed": 613386174, + "version": 3, + "versionNonce": 192248482, + "isDeleted": true, + "boundElements": null, + "updated": 1774254617272, + "link": null, + "locked": false, + "text": "", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "mwO7qxMieKLSg6XF7sIgg", + "type": "text", + "x": -5960, + "y": 2980, + "width": 176.06385803222656, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7p", + "roundness": null, + "seed": 309303934, + "version": 198, + "versionNonce": 1615560190, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "POST / payment_intents", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "POST / payment_intents", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "CHXcZ-J-AdtlSPxiCUvvK", + "type": "text", + "x": -5980, + "y": 3040, + "width": 219.34378051757812, + "height": 40, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7q", + "roundness": null, + "seed": 565838078, + "version": 229, + "versionNonce": 1885802046, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Payment intent + client_secret\n ", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Payment intent + client_secret\n ", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "4wQRMxtBYNs4IzQgG0gbx", + "type": "text", + "x": -680, + "y": 1000, + "width": 208.52786254882812, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7r", + "roundness": null, + "seed": 1540253438, + "version": 143, + "versionNonce": 647116222, + "isDeleted": true, + "boundElements": [], + "updated": 1774255238463, + "link": null, + "locked": false, + "text": "Build template, validate data", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Build template, validate data", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "d8RzvAIJDWOPamBa0cKkn", + "type": "text", + "x": -680, + "y": 1160, + "width": 177.0718536376953, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7s", + "roundness": null, + "seed": 1951815330, + "version": 190, + "versionNonce": 725194978, + "isDeleted": true, + "boundElements": [], + "updated": 1774255240252, + "link": null, + "locked": false, + "text": "Log result, handle errors", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Log result, handle errors", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "6vKBT39NJ847mkXo3ecqC", + "type": "arrow", + "x": -571.7294110964202, + "y": 1186, + "width": 111.72941109642022, + "height": 34, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7t", + "roundness": { + "type": 2 + }, + "seed": 1590895714, + "version": 29, + "versionNonce": 904903166, + "isDeleted": true, + "boundElements": null, + "updated": 1774254815421, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 111.72941109642022, + 34 + ] + ], + "startBinding": { + "elementId": "d8RzvAIJDWOPamBa0cKkn", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "-9oHgyv1pDdU3RnnPqIu0", + "type": "arrow", + "x": -1080, + "y": 1160, + "width": 40, + "height": 80, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7u", + "roundness": { + "type": 2 + }, + "seed": 269013694, + "version": 24, + "versionNonce": 1630329122, + "isDeleted": true, + "boundElements": null, + "updated": 1774254887285, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + -80 + ], + [ + 40, + 0 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "type": "arrow", + "version": 2955, + "versionNonce": 1392637886, + "index": "b7v", + "isDeleted": true, + "id": "e7Ztw8TzGuu4SeJ7j6L0L", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1180, + "y": 1140, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 20, + "height": 40, + "seed": 310139518, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774254989781, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -40 + ], + [ + 20, + -40 + ], + [ + 20, + 0 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + -40 + ], + "end": [ + 20, + -40 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 3356, + "versionNonce": 2033520034, + "index": "b7w", + "isDeleted": true, + "id": "sUwxkkve1D1yDgdpedeSW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -593, + "y": 1020, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 20, + "seed": 1700114402, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774255237539, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ], + [ + 40, + 20 + ], + [ + 0, + 20 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 40, + 0 + ], + "end": [ + 40, + 20 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 3500, + "versionNonce": 1327928958, + "index": "b7x", + "isDeleted": false, + "id": "xRMTeWIYnA6_8dophiQX4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6112, + "y": 3460, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 20, + "seed": 1681388322, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ], + [ + 40, + 20 + ], + [ + 0, + 20 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 40, + 0 + ], + "end": [ + 40, + 20 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 1143, + "versionNonce": 826248546, + "index": "b7y", + "isDeleted": false, + "id": "2jXpRWoU373rSDdLvc6s4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7240, + "y": 3260, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 919202466, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "V_MN8KstFVkSU_WVlRzb5" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "V_MN8KstFVkSU_WVlRzb5", + "type": "text", + "x": -7225.999900817871, + "y": 3287.5, + "width": 171.9998016357422, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7z", + "roundness": null, + "seed": 1027098210, + "version": 102, + "versionNonce": 107712802, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Integration Module", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "2jXpRWoU373rSDdLvc6s4", + "originalText": "Integration Module", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1195, + "versionNonce": 652287202, + "index": "b80", + "isDeleted": false, + "id": "RtP70CFlTXy2iGAYi3aI-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7580, + "y": 3260, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1692740130, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "m9ebldlIG9W9tdOQzHN2Q" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "m9ebldlIG9W9tdOQzHN2Q", + "type": "text", + "x": -7557.559928894043, + "y": 3287.5, + "width": 155.11985778808594, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b81", + "roundness": null, + "seed": 348100066, + "version": 176, + "versionNonce": 3092642, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Application Code", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "RtP70CFlTXy2iGAYi3aI-", + "originalText": "Application Code", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1195, + "versionNonce": 1980025954, + "index": "b82", + "isDeleted": false, + "id": "Tg_y_jSIp_gEZ1rJGwrtM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6900, + "y": 3260, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 2111211938, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jWbvDpblt33Ifc4lKN2Sr" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "jWbvDpblt33Ifc4lKN2Sr", + "type": "text", + "x": -6878.129905700684, + "y": 3287.5, + "width": 156.2598114013672, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b83", + "roundness": null, + "seed": 1465451874, + "version": 164, + "versionNonce": 506523682, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "External Provider", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Tg_y_jSIp_gEZ1rJGwrtM", + "originalText": "External Provider", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1169, + "versionNonce": 2091031522, + "index": "b84", + "isDeleted": false, + "id": "RwLfCblMdj9CtI0ChMA6f", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7240, + "y": 3660, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 446040354, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "wnwKqgh5hLbXA-QdSX8Io" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "wnwKqgh5hLbXA-QdSX8Io", + "type": "text", + "x": -7225.999900817871, + "y": 3687.5, + "width": 171.9998016357422, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b85", + "roundness": null, + "seed": 1056740578, + "version": 111, + "versionNonce": 1063833506, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Integration Module", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "RwLfCblMdj9CtI0ChMA6f", + "originalText": "Integration Module", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1224, + "versionNonce": 2058521442, + "index": "b86", + "isDeleted": false, + "id": "8boV8KdixAgTQ19eYLAK4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7580, + "y": 3660, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1981524130, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "uagV0_9uCH3JTV1Dr-1mN" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "uagV0_9uCH3JTV1Dr-1mN", + "type": "text", + "x": -7557.559928894043, + "y": 3687.5, + "width": 155.11985778808594, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b87", + "roundness": null, + "seed": 1738687586, + "version": 190, + "versionNonce": 1691275042, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Application Code", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "8boV8KdixAgTQ19eYLAK4", + "originalText": "Application Code", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1215, + "versionNonce": 304913122, + "index": "b88", + "isDeleted": false, + "id": "cFyOGFvrRXoISCxSKwfZa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6900, + "y": 3660, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 200, + "height": 80, + "seed": 1834969122, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "_E6jDapt1A3MFUckyLMo6" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "_E6jDapt1A3MFUckyLMo6", + "type": "text", + "x": -6878.129905700684, + "y": 3687.5, + "width": 156.2598114013672, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b89", + "roundness": null, + "seed": 1329730530, + "version": 168, + "versionNonce": 828042914, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "External Provider", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cFyOGFvrRXoISCxSKwfZa", + "originalText": "External Provider", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "3d3Q8aSBAYb4gIKtKrsot", + "type": "line", + "x": -7140, + "y": 3340, + "width": 0, + "height": 320, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8A", + "roundness": null, + "seed": 2136557474, + "version": 116, + "versionNonce": 1191758434, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 320 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "xlpgKzYr6OgHI6zoU_12I", + "type": "line", + "x": -7480, + "y": 3340, + "width": 0, + "height": 320, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8B", + "roundness": null, + "seed": 1439957858, + "version": 155, + "versionNonce": 1778724386, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 320 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "PlYK08WPSPJIw3fnk0fce", + "type": "line", + "x": -6800, + "y": 3340, + "width": 0, + "height": 320, + "angle": 0, + "strokeColor": "#17c4b7", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8C", + "roundness": null, + "seed": 1291929378, + "version": 173, + "versionNonce": 2134841826, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 320 + ] + ], + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "polygon": false + }, + { + "id": "wmE3zLv74TGqzrnHHXzxQ", + "type": "rectangle", + "x": -7145, + "y": 3380, + "width": 10, + "height": 240, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8D", + "roundness": null, + "seed": 1028657890, + "version": 108, + "versionNonce": 1975881122, + "isDeleted": false, + "boundElements": [ + { + "id": "ZFRVxY_clX6Z3bKE7ORyC", + "type": "arrow" + }, + { + "id": "FHnj-sZkXGZJRs9GWZIBR", + "type": "arrow" + }, + { + "id": "fdtYNlb8zVJfvfLv29C2S", + "type": "arrow" + }, + { + "id": "PJ1jPZf2E5SsHTzgP7B1a", + "type": "arrow" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "id": "HUPrCh76fK3DwZ57eRCT5", + "type": "rectangle", + "x": -6805, + "y": 3480, + "width": 10, + "height": 60, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8E", + "roundness": null, + "seed": 424634018, + "version": 154, + "versionNonce": 46631266, + "isDeleted": false, + "boundElements": [ + { + "id": "PJ1jPZf2E5SsHTzgP7B1a", + "type": "arrow" + }, + { + "id": "fdtYNlb8zVJfvfLv29C2S", + "type": "arrow" + } + ], + "updated": 1774255079972, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 2409, + "versionNonce": 1569983778, + "index": "b8F", + "isDeleted": false, + "id": "ZFRVxY_clX6Z3bKE7ORyC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7480, + "y": 3380, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 329.00011655587946, + "height": 0.005037506026042138, + "seed": 699286114, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "wmE3zLv74TGqzrnHHXzxQ", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 329.00011655587946, + -0.005037506026042138 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2807, + "versionNonce": 2073696482, + "index": "b8G", + "isDeleted": false, + "id": "PJ1jPZf2E5SsHTzgP7B1a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7129, + "y": 3480.453226654675, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 317.9999999999999, + "height": 0.4380718483732835, + "seed": 1228645922, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": { + "elementId": "wmE3zLv74TGqzrnHHXzxQ", + "mode": "orbit", + "fixedPoint": [ + 0.5923167880269602, + 0.4186129514237317 + ] + }, + "endBinding": { + "elementId": "HUPrCh76fK3DwZ57eRCT5", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 317.9999999999999, + -0.4380718483732835 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2875, + "versionNonce": 1281928354, + "index": "b8H", + "isDeleted": false, + "id": "fdtYNlb8zVJfvfLv29C2S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6810.999839060577, + "y": 3540.0118485178073, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 318.0001609394228, + "height": 0.25449079698023525, + "seed": 551981538, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": { + "elementId": "HUPrCh76fK3DwZ57eRCT5", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": { + "elementId": "wmE3zLv74TGqzrnHHXzxQ", + "mode": "orbit", + "fixedPoint": [ + 0.6847137431712099, + 0.6678072871618582 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -318.0001609394228, + 0.25449079698023525 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 2824, + "versionNonce": 1974388834, + "index": "b8I", + "isDeleted": false, + "id": "FHnj-sZkXGZJRs9GWZIBR", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7150.99988344412, + "y": 3620.005037506028, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 329.0001165558797, + "height": 0.005037506028429561, + "seed": 1673397666, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": { + "elementId": "wmE3zLv74TGqzrnHHXzxQ", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -329.0001165558797, + -0.005037506028429561 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "KuaX3qAbPo-jJ6C9_zoOc", + "type": "text", + "x": -7440, + "y": 3360, + "width": 241.11973571777344, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8J", + "roundness": null, + "seed": 183566690, + "version": 68, + "versionNonce": 255552546, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "emailService.sendWelcome(user)", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "emailService.sendWelcome(user)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "GrUr8fUWQZXm6Y15wyjLs", + "type": "text", + "x": -7400, + "y": 3600, + "width": 187.39183044433594, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8K", + "roundness": null, + "seed": 298747170, + "version": 98, + "versionNonce": 1593677794, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Success / throw exception", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Success / throw exception", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "B9kXcGO8Km_etX_4MgC4S", + "type": "text", + "x": -7060, + "y": 3460, + "width": 180.87982177734375, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8L", + "roundness": null, + "seed": 835031266, + "version": 144, + "versionNonce": 352603042, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "POST /api/send (API call)", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "POST /api/send (API call)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "aWaXJ_XWEIWsA1ylSq_GY", + "type": "text", + "x": -7020, + "y": 3520, + "width": 104.19192504882812, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8M", + "roundness": null, + "seed": 509944994, + "version": 170, + "versionNonce": 125732706, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "200 OK / Error", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "200 OK / Error", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "q99o5CJWc3Jz2QxL6miFW", + "type": "text", + "x": -7220, + "y": 3400, + "width": 208.52786254882812, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8N", + "roundness": null, + "seed": 1096564834, + "version": 196, + "versionNonce": 1857768226, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Build template, validate data", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Build template, validate data", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "XfHdyGmk7gf-35cBoCY5k", + "type": "text", + "x": -7220, + "y": 3560, + "width": 177.0718536376953, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8O", + "roundness": null, + "seed": 1987699746, + "version": 243, + "versionNonce": 556373730, + "isDeleted": false, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "text": "Log result, handle errors", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Log result, handle errors", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 3409, + "versionNonce": 1331194530, + "index": "b8P", + "isDeleted": false, + "id": "z-PmWsTH3dTJzmM6mxYd-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7133, + "y": 3420, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 20, + "seed": 1202524130, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ], + [ + 40, + 20 + ], + [ + 0, + 20 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 40, + 0 + ], + "end": [ + 40, + 20 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 3421, + "versionNonce": 1073137250, + "index": "b8Q", + "isDeleted": false, + "id": "pEJQd_UhzR6i_vsUDIH54", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7133, + "y": 3580, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40, + "height": 20, + "seed": 688178082, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774255079972, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ], + [ + 40, + 20 + ], + [ + 0, + 20 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 40, + 0 + ], + "end": [ + 40, + 20 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "id": "n2UxwlzZTtftfiHxjjdLE", + "type": "rectangle", + "x": -6125, + "y": 3360, + "width": 10, + "height": 240, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8R", + "roundness": null, + "seed": 346955618, + "version": 152, + "versionNonce": 1967855294, + "isDeleted": false, + "boundElements": [ + { + "id": "0s40WIdFwbsOEigs0ZYj7", + "type": "arrow" + }, + { + "id": "a78PokSU_JgM5GN7hOQ37", + "type": "arrow" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "3LABp-NAfPAXcEbAse66B", + "type": "rectangle", + "x": -5645, + "y": 3200, + "width": 10, + "height": 60, + "angle": 0, + "strokeColor": "#868e96", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8S", + "roundness": null, + "seed": 1001773986, + "version": 200, + "versionNonce": 460689150, + "isDeleted": false, + "boundElements": [ + { + "id": "qhe_8-Qztef4E3cR8ivoz", + "type": "arrow" + }, + { + "id": "zczRRwQmyP6W1M0itRrxj", + "type": "arrow" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 2883, + "versionNonce": 1042743102, + "index": "b8T", + "isDeleted": false, + "id": "qhe_8-Qztef4E3cR8ivoz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6460, + "y": 3200, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 809.0001165558796, + "height": 0.005037506025928451, + "seed": 659563618, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "3LABp-NAfPAXcEbAse66B", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 809.0001165558796, + -0.005037506025928451 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "6XTTmNgZjOVGye43zXbPc", + "type": "text", + "x": -6180, + "y": 3180, + "width": 222.6558074951172, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8U", + "roundness": null, + "seed": 596039010, + "version": 262, + "versionNonce": 566257534, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Confirm payment (card details)", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Confirm payment (card details)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2975, + "versionNonce": 1451411390, + "index": "b8V", + "isDeleted": false, + "id": "zczRRwQmyP6W1M0itRrxj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5650.99988344412, + "y": 3260.005037506025, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 809.0001165558795, + "height": 0.005037506025018956, + "seed": 710566654, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": { + "elementId": "3LABp-NAfPAXcEbAse66B", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -809.0001165558795, + -0.005037506025018956 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "4iuDB5ZFkS65Rr7fLlBPI", + "type": "text", + "x": -6120, + "y": 3240, + "width": 109.32789611816406, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8W", + "roundness": null, + "seed": 1494282174, + "version": 292, + "versionNonce": 1016012798, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Payment result", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Payment result", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2956, + "versionNonce": 132542526, + "index": "b8X", + "isDeleted": false, + "id": "0s40WIdFwbsOEigs0ZYj7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -5640, + "y": 3360, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 469.0001165558797, + "height": 0.005037506028429561, + "seed": 443702142, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "n2UxwlzZTtftfiHxjjdLE", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -469.0001165558797, + -0.005037506028429561 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "JhaCBD-L1nz80YOilqxTj", + "type": "text", + "x": -473.08799743652344, + "y": 1150.2232785636834, + "width": 4.175994873046875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8Y", + "roundness": null, + "seed": 1624468670, + "version": 3, + "versionNonce": 683156770, + "isDeleted": true, + "boundElements": null, + "updated": 1774255365027, + "link": null, + "locked": false, + "text": "", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0s40WIdFwbsOEigs0ZYj7", + "originalText": "", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2900, + "versionNonce": 811038718, + "index": "b8Z", + "isDeleted": true, + "id": "-kv2AkdiyHqRwC0J_Crer", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -270.9998834441203, + "y": 1520.0050375060284, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 469.0001165558797, + "height": 0.005037506028429561, + "seed": 868487650, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255386312, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -469.0001165558797, + -0.005037506028429561 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 3125, + "versionNonce": 1147779198, + "index": "b8a", + "isDeleted": false, + "id": "a78PokSU_JgM5GN7hOQ37", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6109.00011655588, + "y": 3600.005037506026, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 469.00011655587946, + "height": 0.005037506025928451, + "seed": 1709817442, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "startBinding": { + "elementId": "n2UxwlzZTtftfiHxjjdLE", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 1 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 469.00011655587946, + -0.005037506025928451 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "id": "4fP5d3V8gGiPkKY64QODZ", + "type": "text", + "x": -5900, + "y": 3580, + "width": 55.455963134765625, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8b", + "roundness": null, + "seed": 1268587426, + "version": 323, + "versionNonce": 1507457214, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "200 OK", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "200 OK", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "aQqZG2GScGrR3Ec7mhX5J", + "type": "text", + "x": -6000, + "y": 3360, + "width": 271.0877685546875, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8c", + "roundness": null, + "seed": 313475198, + "version": 388, + "versionNonce": 265826558, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Webhook: payment_intent.succeeded", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Webhook: payment_intent.succeeded", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "TAoHdPcHVIxlcYflV5tvt", + "type": "text", + "x": -6240, + "y": 3440, + "width": 214.84780883789062, + "height": 20, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#ced4da", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8d", + "roundness": null, + "seed": 2067437218, + "version": 360, + "versionNonce": 300245310, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Verify signature, update order", + "fontSize": 16, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Verify signature, update order", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1309, + "versionNonce": 1935837566, + "index": "b8e", + "isDeleted": false, + "id": "58Uf84QNIEV-HB1urfJ5h", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -6160, + "y": 3280, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 560, + "height": 60, + "seed": 1286414178, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "WXBwO-lNwBPbVQqGg0FSR" + } + ], + "updated": 1774255562360, + "link": null, + "locked": false + }, + { + "id": "WXBwO-lNwBPbVQqGg0FSR", + "type": "text", + "x": -6027.909851074219, + "y": 3297.5, + "width": 295.8197021484375, + "height": 25, + "angle": 0, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b8f", + "roundness": null, + "seed": 1112990498, + "version": 306, + "versionNonce": 865118654, + "isDeleted": false, + "boundElements": [], + "updated": 1774255562360, + "link": null, + "locked": false, + "text": "Asynchronous webhook callback", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "58Uf84QNIEV-HB1urfJ5h", + "originalText": "Asynchronous webhook callback", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 2606, + "versionNonce": 1365333474, + "index": "b8g", + "isDeleted": true, + "id": "pKlPaSqA1V_2oPJ6NefYj", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 500, + "y": 2000, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 740, + "seed": 43497506, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034465, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2715, + "versionNonce": 1886449982, + "index": "b8h", + "isDeleted": true, + "id": "dx03sqou-lDgfYtqi5Lvs", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 280, + "y": 2780, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1080, + "height": 300, + "seed": 368738210, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034465, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1400, + "versionNonce": 1077954978, + "index": "b8i", + "isDeleted": true, + "id": "_xxY-XFKX8jGgoh0RNdEv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 700, + "y": 2020, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 199.807861328125, + "height": 37.800000000000004, + "seed": 1214247422, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034465, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Our Application", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Our Application", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1448, + "versionNonce": 435951998, + "index": "b8j", + "isDeleted": true, + "id": "0LZF-VFSWuISeOCyYIkU-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 80, + "y": 2160, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 137.3118896484375, + "height": 37.800000000000004, + "seed": 1568071358, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034465, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Monitoring", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Monitoring", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1502, + "versionNonce": 646628706, + "index": "b8k", + "isDeleted": true, + "id": "DOZGuJMdcB90gNlOM8RaT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 700, + "y": 2800, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 196.6998748779297, + "height": 37.800000000000004, + "seed": 1229981986, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034465, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Communication", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Communication", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3296, + "versionNonce": 1886927294, + "index": "b8l", + "isDeleted": true, + "id": "AM1hr5Y0S7D5t_S5KqP-C", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 660, + "y": 2480, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 120.00000000000001, + "seed": 491805822, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "C-4CNujtlrFLH7nQ7VCPz" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3479, + "versionNonce": 495962402, + "index": "b8m", + "isDeleted": true, + "id": "C-4CNujtlrFLH7nQ7VCPz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 677.9620666503906, + "y": 2502.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 244.07586669921875, + "height": 75.60000000000001, + "seed": 642522302, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Integration Layer\nDedicated Modules", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "AM1hr5Y0S7D5t_S5KqP-C", + "originalText": "Integration Layer\nDedicated Modules", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3341, + "versionNonce": 453399038, + "index": "b8n", + "isDeleted": true, + "id": "SgpGnzdwRY2_n41Rck9RL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 660, + "y": 2140, + "strokeColor": "#ffffff", + "backgroundColor": "#1677fa", + "width": 280, + "height": 120.00000000000001, + "seed": 1565685950, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "8eLpYXZ1Z_kMzYdIZWKsm" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3534, + "versionNonce": 1019106530, + "index": "b8o", + "isDeleted": true, + "id": "8eLpYXZ1Z_kMzYdIZWKsm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 730.6580352783203, + "y": 2181.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 138.68392944335938, + "height": 37.800000000000004, + "seed": 272675070, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "NestJS API", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "SgpGnzdwRY2_n41Rck9RL", + "originalText": "NestJS API", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3394, + "versionNonce": 883384894, + "index": "b8p", + "isDeleted": true, + "id": "-LmEm61D-WcNcydWPZeV4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 300, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 280, + "height": 120.00000000000001, + "seed": 1241074878, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "l36-BjauFF2o-yvZBo0sL" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3625, + "versionNonce": 1436903586, + "index": "b8q", + "isDeleted": true, + "id": "l36-BjauFF2o-yvZBo0sL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 315.24605560302734, + "y": 2902.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 249.5078887939453, + "height": 75.60000000000001, + "seed": 1760363774, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Email Service\nResend / OneSignal", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-LmEm61D-WcNcydWPZeV4", + "originalText": "Email Service\nResend / OneSignal", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3419, + "versionNonce": 1346136702, + "index": "b8r", + "isDeleted": true, + "id": "49j90uM8zzTXmLD0gYj0u", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 600, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 360, + "height": 124, + "seed": 967162850, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "porcqwkiXQ3XT78SczznT" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3699, + "versionNonce": 804521058, + "index": "b8s", + "isDeleted": true, + "id": "porcqwkiXQ3XT78SczznT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 609.3821105957031, + "y": 2904.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 341.23577880859375, + "height": 75.60000000000001, + "seed": 789049250, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Firebase Cloud Messaging \nPush Notifications", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "49j90uM8zzTXmLD0gYj0u", + "originalText": "Firebase Cloud Messaging \nPush Notifications", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3467, + "versionNonce": 2089183934, + "index": "b8t", + "isDeleted": true, + "id": "aRfQ85nM1sfNJXQ1hYyNs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 980, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 360, + "height": 124, + "seed": 2089469438, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "o71b3GwZKe39L3Mo20Mdv" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3733, + "versionNonce": 1165568034, + "index": "b8u", + "isDeleted": true, + "id": "o71b3GwZKe39L3Mo20Mdv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1024.2001037597656, + "y": 2904.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 271.59979248046875, + "height": 75.60000000000001, + "seed": 1434277438, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Slack API\nAlerts & Notifications", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "aRfQ85nM1sfNJXQ1hYyNs", + "originalText": "Slack API\nAlerts & Notifications", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3448, + "versionNonce": 1210475262, + "index": "b8v", + "isDeleted": true, + "id": "MvjzWM0o2B9IvUmAmQ4WD", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -660, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 1224907326, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "pZN54ubPcNxfmz5vmdn4D" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3698, + "versionNonce": 2116277218, + "index": "b8w", + "isDeleted": true, + "id": "pZN54ubPcNxfmz5vmdn4D", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -608.7319412231445, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 177.46388244628906, + "height": 37.800000000000004, + "seed": 611361406, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Firebase Auth", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MvjzWM0o2B9IvUmAmQ4WD", + "originalText": "Firebase Auth", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3465, + "versionNonce": 1167938366, + "index": "b8x", + "isDeleted": true, + "id": "nyi6F6nlAbF1iufbzUJsM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -360, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 2036023074, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "RlxjmqIcO5SJ2dFUS_PHV" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3728, + "versionNonce": 1812137890, + "index": "b8y", + "isDeleted": true, + "id": "RlxjmqIcO5SJ2dFUS_PHV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -311.33595275878906, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 182.67190551757812, + "height": 37.800000000000004, + "seed": 1001065186, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google OAuth", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "nyi6F6nlAbF1iufbzUJsM", + "originalText": "Google OAuth", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3478, + "versionNonce": 256654206, + "index": "b8z", + "isDeleted": true, + "id": "SmObHf-3hfYxrQrzez7x4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -60, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 1094112510, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "fUeFzEmCDXjNVoPiHDiy7" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3761, + "versionNonce": 122012514, + "index": "b90", + "isDeleted": true, + "id": "fUeFzEmCDXjNVoPiHDiy7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -7.86395263671875, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 175.7279052734375, + "height": 37.800000000000004, + "seed": 1741653310, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Apple Sign-In", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "SmObHf-3hfYxrQrzez7x4", + "originalText": "Apple Sign-In", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3478, + "versionNonce": 1265900478, + "index": "b91", + "isDeleted": true, + "id": "1jYgOtqkoosZBQgJBgoFV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1420, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 280, + "height": 120.00000000000001, + "seed": 544131746, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "lMnFyY2QiLVa_lI9oqKIO" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3767, + "versionNonce": 1782253346, + "index": "b92", + "isDeleted": true, + "id": "lMnFyY2QiLVa_lI9oqKIO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1522.2560272216797, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 75.48794555664062, + "height": 37.800000000000004, + "seed": 1598105186, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Stripe", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1jYgOtqkoosZBQgJBgoFV", + "originalText": "Stripe", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3506, + "versionNonce": 808842238, + "index": "b93", + "isDeleted": true, + "id": "ZpyWvBBzhMhNUhb4_Q3P-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1740, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 280, + "height": 120.00000000000001, + "seed": 1484241406, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "WzvY661SC-1EwWh4QGXNG" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3801, + "versionNonce": 223466210, + "index": "b94", + "isDeleted": true, + "id": "WzvY661SC-1EwWh4QGXNG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1838.7420120239258, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 82.51597595214844, + "height": 37.800000000000004, + "seed": 262916670, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "GoPay", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ZpyWvBBzhMhNUhb4_Q3P-", + "originalText": "GoPay", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3583, + "versionNonce": 127059006, + "index": "b95", + "isDeleted": true, + "id": "XoGYOoHWs0_bzyVC6ipI7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 20, + "y": 2260, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 219639330, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "03qiI3iAYcig6WrZyIVza" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3899, + "versionNonce": 51979938, + "index": "b96", + "isDeleted": true, + "id": "03qiI3iAYcig6WrZyIVza", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 71.94007110595703, + "y": 2282.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 176.11985778808594, + "height": 75.60000000000001, + "seed": 101276130, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Sentry\nError Tracking", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "XoGYOoHWs0_bzyVC6ipI7", + "originalText": "Sentry\nError Tracking", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3589, + "versionNonce": 862686334, + "index": "b97", + "isDeleted": true, + "id": "9WaoQa_hEpoJJl4_kYk-V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 20, + "y": 2400, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 1628380670, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ZetmD3l7DTuOJWrdY3i8P" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3922, + "versionNonce": 876610146, + "index": "b98", + "isDeleted": true, + "id": "ZetmD3l7DTuOJWrdY3i8P", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 51.696067810058594, + "y": 2441.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 216.6078643798828, + "height": 37.800000000000004, + "seed": 1471589950, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google Analytics", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "9WaoQa_hEpoJJl4_kYk-V", + "originalText": "Google Analytics", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3639, + "versionNonce": 830557374, + "index": "b99", + "isDeleted": true, + "id": "px2wJ0CBBPboO-lZXfeiw", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1300, + "y": 2260, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 120.00000000000001, + "seed": 1677595838, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "2bhuB6OPOJsHNjiA23rV2" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4013, + "versionNonce": 462775842, + "index": "b9A", + "isDeleted": true, + "id": "2bhuB6OPOJsHNjiA23rV2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1379.6880264282227, + "y": 2301.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 120.62394714355469, + "height": 37.800000000000004, + "seed": 1998114046, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Database", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "px2wJ0CBBPboO-lZXfeiw", + "originalText": "Database", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3593, + "versionNonce": 1820130850, + "index": "b9B", + "isDeleted": true, + "id": "Ub7PI4qRTK8GUC_NYUzit", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1300, + "y": 2300, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 999356898, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jgSUenxcl9Smb17-homhC" + } + ], + "updated": 1774257531233, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3927, + "versionNonce": 1685253374, + "index": "b9C", + "isDeleted": true, + "id": "jgSUenxcl9Smb17-homhC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1331.6960678100586, + "y": 2341.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 216.6078643798828, + "height": 37.800000000000004, + "seed": 215707042, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774257531233, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google Analytics", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Ub7PI4qRTK8GUC_NYUzit", + "originalText": "Google Analytics", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3643, + "versionNonce": 527762686, + "index": "b9D", + "isDeleted": true, + "id": "L_LVzfqs9gpg1xHFDaAvT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1300, + "y": 2400, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 120.00000000000001, + "seed": 852813246, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "3T4qWBmzQtckeOdnsj-U5" + } + ], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4008, + "versionNonce": 34099682, + "index": "b9E", + "isDeleted": true, + "id": "3T4qWBmzQtckeOdnsj-U5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1327.1460418701172, + "y": 2422.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 225.70791625976562, + "height": 75.60000000000001, + "seed": 1156414974, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Storegae\nGCS / Spaces / S3", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "L_LVzfqs9gpg1xHFDaAvT", + "originalText": "Cloud Storegae\nGCS / Spaces / S3", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2644, + "versionNonce": 1053275454, + "index": "b9F", + "isDeleted": true, + "id": "5xu5I04qXCVPbe7L1BOfj", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1140, + "y": 2140, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 600, + "seed": 346426046, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2679, + "versionNonce": 984073634, + "index": "b9G", + "isDeleted": true, + "id": "mneKisbluERNsrE-1-BYv", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -140, + "y": 2140, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 600, + "seed": 742876834, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1498, + "versionNonce": 2027576702, + "index": "b9H", + "isDeleted": true, + "id": "4nMGLYBFNPSfW5vrinJYh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1360, + "y": 2160, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 194.2919158935547, + "height": 37.800000000000004, + "seed": 1679968958, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Storage & Data", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Storage & Data", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2685, + "versionNonce": 1587724642, + "index": "b9I", + "isDeleted": true, + "id": "iuLjQWEvXvmgzZQW1mQWE", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1400, + "y": 2780, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 640.0000000000001, + "height": 300, + "seed": 866174114, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1562, + "versionNonce": 1659764158, + "index": "b9J", + "isDeleted": true, + "id": "qX79VJ-l6EdRk7O2rDegY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1680, + "y": 2800, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 125.04794311523438, + "height": 37.800000000000004, + "seed": 1138939810, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Payments", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Payments", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2749, + "versionNonce": 155731234, + "index": "b9K", + "isDeleted": true, + "id": "ZuA8mQZiNoVNZQouhkjtn", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -680, + "y": 2780, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 920, + "height": 300, + "seed": 1801731518, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259034466, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2791, + "versionNonce": 1844628834, + "index": "b9L", + "isDeleted": true, + "id": "Tl_B4NAPexXpNQOIR5-SF", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 3300, + "y": 3340, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 1080, + "height": 300, + "seed": 2082470526, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259030608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1518, + "versionNonce": 1174072802, + "index": "b9M", + "isDeleted": false, + "id": "i-s29d4bgjeJGlzLiyd-m", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8900, + "y": 2480, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 199.807861328125, + "height": 37.800000000000004, + "seed": 91749054, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Our Application", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Our Application", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1565, + "versionNonce": 501670306, + "index": "b9N", + "isDeleted": false, + "id": "nY1BmqYOdrMIbEruuvpcQ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9520, + "y": 2620, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 137.3118896484375, + "height": 37.800000000000004, + "seed": 1550185214, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Monitoring", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Monitoring", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1619, + "versionNonce": 1134452066, + "index": "b9O", + "isDeleted": false, + "id": "U3unsg939Mp8YNcKUQyPz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8900, + "y": 3260, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 196.6998748779297, + "height": 37.800000000000004, + "seed": 1265296190, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Communication", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Communication", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3429, + "versionNonce": 74473762, + "index": "b9P", + "isDeleted": false, + "id": "QP2swWZwKIUNmJFMsKa9F", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8940, + "y": 2960, + "strokeColor": "#ffffff", + "backgroundColor": "#8a84d6", + "width": 280, + "height": 140.00000000000003, + "seed": 619170686, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "ZhbUzZBQ98CjSH3_k6Ojd" + }, + { + "id": "5EHGV6fnCwaYVGpRMfIFi", + "type": "arrow" + }, + { + "id": "CEYL0u8W-q6hARVJiuXqx", + "type": "arrow" + }, + { + "id": "6vm2-UsZEsH8TJAt2XF91", + "type": "arrow" + }, + { + "id": "rNzFLDTlFrKhXD8I-DWym", + "type": "arrow" + }, + { + "id": "KDj_pySRY-a4_6AtuSH9K", + "type": "arrow" + }, + { + "id": "BLYoQHoxrsYAunwIS-qxX", + "type": "arrow" + }, + { + "id": "d9ivtAVmxoRVCNaIBclhv", + "type": "arrow" + }, + { + "id": "LKKDODOY8WCuSLN0fqIhB", + "type": "arrow" + }, + { + "id": "zmQa1myT7Zv9BqPrG2Rc7", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3600, + "versionNonce": 734784738, + "index": "b9Q", + "isDeleted": false, + "id": "ZhbUzZBQ98CjSH3_k6Ojd", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8922.03793334961, + "y": 2992.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 244.07586669921875, + "height": 75.60000000000001, + "seed": 1193126846, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Integration Layer\nDedicated Modules", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QP2swWZwKIUNmJFMsKa9F", + "originalText": "Integration Layer\nDedicated Modules", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3463, + "versionNonce": 1061159074, + "index": "b9R", + "isDeleted": false, + "id": "uXRCx2XGVmAnC2YOkC7Zi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8940, + "y": 2640, + "strokeColor": "#ffffff", + "backgroundColor": "#1677fa", + "width": 280, + "height": 120.00000000000001, + "seed": 539853822, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "nune3aH4N5Rb7PdyuClR9" + }, + { + "id": "kU4vmpvMKDDKInaJFBJqJ", + "type": "arrow" + }, + { + "id": "yTndQFGb2OqrLkDZ9DALY", + "type": "arrow" + }, + { + "id": "7vZ-YT-Ga_VtUw0r2p184", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3654, + "versionNonce": 981179490, + "index": "b9S", + "isDeleted": false, + "id": "nune3aH4N5Rb7PdyuClR9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8869.34196472168, + "y": 2681.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 138.68392944335938, + "height": 37.800000000000004, + "seed": 840455230, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "NestJS API", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "uXRCx2XGVmAnC2YOkC7Zi", + "originalText": "NestJS API", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3535, + "versionNonce": 1263386658, + "index": "b9T", + "isDeleted": false, + "id": "u0xFgjkYZAVJkZajG0-lO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8940, + "y": 3620, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 280, + "height": 120.00000000000001, + "seed": 381623422, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5zocDIUSuDQheOmtKhUZK" + }, + { + "id": "LKKDODOY8WCuSLN0fqIhB", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3765, + "versionNonce": 228944866, + "index": "b9U", + "isDeleted": false, + "id": "5zocDIUSuDQheOmtKhUZK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8924.753944396973, + "y": 3642.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 249.5078887939453, + "height": 75.60000000000001, + "seed": 65199294, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Email Service\nResend / OneSignal", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "u0xFgjkYZAVJkZajG0-lO", + "originalText": "Email Service\nResend / OneSignal", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3539, + "versionNonce": 1200725922, + "index": "b9V", + "isDeleted": false, + "id": "831lZwuEF8HMkL7hx6Npp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8980, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 360, + "height": 124, + "seed": 1327797502, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "bS0GQLvK7wqVZWUL5537e" + }, + { + "id": "LKKDODOY8WCuSLN0fqIhB", + "type": "arrow" + }, + { + "id": "zmQa1myT7Zv9BqPrG2Rc7", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3817, + "versionNonce": 625040226, + "index": "b9W", + "isDeleted": false, + "id": "bS0GQLvK7wqVZWUL5537e", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8970.617889404297, + "y": 3364.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 341.23577880859375, + "height": 75.60000000000001, + "seed": 1912948030, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Firebase Cloud Messaging \nPush Notifications", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "831lZwuEF8HMkL7hx6Npp", + "originalText": "Firebase Cloud Messaging \nPush Notifications", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3610, + "versionNonce": 1963171618, + "index": "b9X", + "isDeleted": false, + "id": "30x4AZdPbcjjkhJ9_d2zt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8980, + "y": 3480, + "strokeColor": "#ffffff", + "backgroundColor": "#15aabf", + "width": 360, + "height": 124, + "seed": 233172350, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "5hoQotRArLPhlqVBnN5d4" + }, + { + "id": "AXRKzYQWEPTZMrEbSnFXg", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3875, + "versionNonce": 1665624802, + "index": "b9Y", + "isDeleted": false, + "id": "5hoQotRArLPhlqVBnN5d4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8935.799896240234, + "y": 3504.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 271.59979248046875, + "height": 75.60000000000001, + "seed": 1879543230, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Slack API\nAlerts & Notifications", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "30x4AZdPbcjjkhJ9_d2zt", + "originalText": "Slack API\nAlerts & Notifications", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3591, + "versionNonce": 916176546, + "index": "b9Z", + "isDeleted": false, + "id": "aizFvR-aD6OZ5iyPOCgBH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9580, + "y": 3620, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 361440766, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "LhppNTDzDRsDK-YP23ik2" + }, + { + "id": "KDj_pySRY-a4_6AtuSH9K", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3841, + "versionNonce": 196057698, + "index": "b9a", + "isDeleted": false, + "id": "LhppNTDzDRsDK-YP23ik2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9528.731941223145, + "y": 3661.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 177.46388244628906, + "height": 37.800000000000004, + "seed": 795981374, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Firebase Auth", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "aizFvR-aD6OZ5iyPOCgBH", + "originalText": "Firebase Auth", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3601, + "versionNonce": 290586146, + "index": "b9b", + "isDeleted": false, + "id": "CpeSKlNPHRLoaq3jsfuxr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9580, + "y": 3480, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 647773822, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Ax5aRonaQlP9kW9SXV3NX" + }, + { + "id": "rNzFLDTlFrKhXD8I-DWym", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3864, + "versionNonce": 1148316130, + "index": "b9c", + "isDeleted": false, + "id": "Ax5aRonaQlP9kW9SXV3NX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9531.335952758789, + "y": 3521.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 182.67190551757812, + "height": 37.800000000000004, + "seed": 533446334, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google OAuth", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "CpeSKlNPHRLoaq3jsfuxr", + "originalText": "Google OAuth", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3600, + "versionNonce": 740187554, + "index": "b9d", + "isDeleted": false, + "id": "BkiR3xiMELGC4ZUdjFozZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9580, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#fab005", + "width": 280, + "height": 120.00000000000001, + "seed": 2141271806, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "eb4V8VimfZootsoiusE5k" + }, + { + "id": "6vm2-UsZEsH8TJAt2XF91", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3883, + "versionNonce": 361126242, + "index": "b9e", + "isDeleted": false, + "id": "eb4V8VimfZootsoiusE5k", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9527.863952636719, + "y": 3381.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 175.7279052734375, + "height": 37.800000000000004, + "seed": 1855825726, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Apple Sign-In", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "BkiR3xiMELGC4ZUdjFozZ", + "originalText": "Apple Sign-In", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3602, + "versionNonce": 1341709602, + "index": "b9f", + "isDeleted": false, + "id": "ItloWTyf24bCMkzBZL3Zn", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8260, + "y": 3340, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 280, + "height": 120.00000000000001, + "seed": 1562513278, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "qYZID0d6voWQ55prZ6OZq" + }, + { + "id": "d9ivtAVmxoRVCNaIBclhv", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3891, + "versionNonce": 1759832290, + "index": "b9g", + "isDeleted": false, + "id": "qYZID0d6voWQ55prZ6OZq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8157.74397277832, + "y": 3381.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 75.48794555664062, + "height": 37.800000000000004, + "seed": 124743614, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Stripe", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "ItloWTyf24bCMkzBZL3Zn", + "originalText": "Stripe", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3648, + "versionNonce": 1742306466, + "index": "b9h", + "isDeleted": false, + "id": "aLxODB5MmtDLve4n-s97h", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8260, + "y": 3480, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 280, + "height": 120.00000000000001, + "seed": 2040973310, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "shEM83dAHa2Io-EyBTI0F" + }, + { + "id": "CEYL0u8W-q6hARVJiuXqx", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3943, + "versionNonce": 176527458, + "index": "b9i", + "isDeleted": false, + "id": "shEM83dAHa2Io-EyBTI0F", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8161.257987976074, + "y": 3521.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 82.51597595214844, + "height": 37.800000000000004, + "seed": 331946046, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "GoPay", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "aLxODB5MmtDLve4n-s97h", + "originalText": "GoPay", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3702, + "versionNonce": 12074018, + "index": "b9j", + "isDeleted": false, + "id": "1KBiGGrJaQQi_CaUq3RFs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9580, + "y": 2740, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 230121598, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "LlikE7Hu21xCbsPI9je4X" + }, + { + "id": "kU4vmpvMKDDKInaJFBJqJ", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4017, + "versionNonce": 677406690, + "index": "b9k", + "isDeleted": false, + "id": "LlikE7Hu21xCbsPI9je4X", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9528.059928894043, + "y": 2762.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 176.11985778808594, + "height": 75.60000000000001, + "seed": 2066915518, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Sentry\nError Tracking", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1KBiGGrJaQQi_CaUq3RFs", + "originalText": "Sentry\nError Tracking", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3708, + "versionNonce": 1233984418, + "index": "b9l", + "isDeleted": false, + "id": "yP4erX1fWBumj9BpqXX-9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9580, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 1339807998, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "V15lbxxaqN5lZEd8Olyj6" + }, + { + "id": "yTndQFGb2OqrLkDZ9DALY", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4041, + "versionNonce": 1382897506, + "index": "b9m", + "isDeleted": false, + "id": "V15lbxxaqN5lZEd8Olyj6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9548.303932189941, + "y": 2921.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 216.6078643798828, + "height": 37.800000000000004, + "seed": 1664354622, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Google Analytics", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yP4erX1fWBumj9BpqXX-9", + "originalText": "Google Analytics", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3758, + "versionNonce": 324016930, + "index": "b9n", + "isDeleted": false, + "id": "L5B-OI8bZQ3Yh8VovmqDH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8300, + "y": 2740, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 120.00000000000001, + "seed": 1956393342, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jont8OeLpbt4Iot93-tdi" + }, + { + "id": "7vZ-YT-Ga_VtUw0r2p184", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4132, + "versionNonce": 2057594594, + "index": "b9o", + "isDeleted": false, + "id": "jont8OeLpbt4Iot93-tdi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8220.311973571777, + "y": 2781.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 120.62394714355469, + "height": 37.800000000000004, + "seed": 794120638, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Database", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "L5B-OI8bZQ3Yh8VovmqDH", + "originalText": "Database", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3762, + "versionNonce": 1358510754, + "index": "b9p", + "isDeleted": false, + "id": "jdBXqVXuHDIqseYY5ec03", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8300, + "y": 2880, + "strokeColor": "#ffffff", + "backgroundColor": "#099268", + "width": 280, + "height": 120.00000000000001, + "seed": 780167678, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "dRyBHmexJNEf2s1degBGi" + }, + { + "id": "BLYoQHoxrsYAunwIS-qxX", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4126, + "versionNonce": 1962776162, + "index": "b9q", + "isDeleted": false, + "id": "dRyBHmexJNEf2s1degBGi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8272.853958129883, + "y": 2902.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 225.70791625976562, + "height": 75.60000000000001, + "seed": 18774590, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Storegae\nGCS / Spaces / S3", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jdBXqVXuHDIqseYY5ec03", + "originalText": "Cloud Storegae\nGCS / Spaces / S3", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2761, + "versionNonce": 394295842, + "index": "b9r", + "isDeleted": false, + "id": "RjWGOzPWkGk5cMyoKVafy", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8460, + "y": 2600, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 600, + "seed": 772833918, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2796, + "versionNonce": 2003887586, + "index": "b9s", + "isDeleted": false, + "id": "VP9UP1Gjza4fdDGrbTba4", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9740, + "y": 2600, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 600, + "seed": 941064894, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1615, + "versionNonce": 501078434, + "index": "b9t", + "isDeleted": false, + "id": "qTU_xuFjifHEEh5eqymQm", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8240, + "y": 2620, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 194.2919158935547, + "height": 37.800000000000004, + "seed": 567573246, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Storage & Data", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Storage & Data", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2829, + "versionNonce": 435574114, + "index": "b9u", + "isDeleted": false, + "id": "RgTK5iHy6H2r8cn3ImBa2", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8460, + "y": 3240, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 640.0000000000001, + "height": 520.0000000000001, + "seed": 1908960062, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1690, + "versionNonce": 1024022818, + "index": "b9v", + "isDeleted": false, + "id": "y6HCSn9AgqHQ47FMLPnuq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8200, + "y": 3260, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 125.04794311523438, + "height": 37.800000000000004, + "seed": 911496062, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Payments", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Payments", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 2906, + "versionNonce": 1451615458, + "index": "b9w", + "isDeleted": false, + "id": "b49oIX5b7yiqNlAzrkbys", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9740, + "y": 3240, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 520.0000000000001, + "seed": 163132350, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2741, + "versionNonce": 1878718626, + "index": "b9x", + "isDeleted": false, + "id": "cjZArVmVZNvEVKt5T9Xnl", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9100, + "y": 2460, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 600, + "height": 740, + "seed": 1402538942, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "tPSC9e8DyQIG4N1-eh1zb", + "type": "arrow" + } + ], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 2777, + "versionNonce": 152540258, + "index": "b9y", + "isDeleted": false, + "id": "y3Xy_kzwvpvFX6iDacWpq", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9100, + "y": 3240, + "strokeColor": "#ced4da", + "backgroundColor": "transparent", + "width": 600, + "height": 520, + "seed": 1364067938, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1661, + "versionNonce": 1403697186, + "index": "b9z", + "isDeleted": false, + "id": "S7dbREoVCCQl6dug5uYlq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -9520, + "y": 3260, + "strokeColor": "#868e96", + "backgroundColor": "transparent", + "width": 186.87185668945312, + "height": 37.800000000000004, + "seed": 1890222910, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Authentication", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Authentication", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 2320, + "versionNonce": 1035532514, + "index": "bA0", + "isDeleted": true, + "id": "2yVmFEbFuSkS2AdnLrywC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 2420, + "y": 1031.4905956490802, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 40.27427037834286, + "height": 191.49059564907998, + "seed": 315110782, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774258104016, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + -95.74529782453999 + ], + [ + 40.27427037834286, + -95.74529782453999 + ], + [ + 40.27427037834286, + -191.49059564907998 + ] + ], + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 4026, + "versionNonce": 1872978914, + "index": "bA1", + "isDeleted": false, + "id": "kU4vmpvMKDDKInaJFBJqJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 2680, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 119.90000000000009, + "seed": 1694545854, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uXRCx2XGVmAnC2YOkC7Zi", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.3333333333333333 + ] + }, + "endBinding": { + "elementId": "1KBiGGrJaQQi_CaUq3RFs", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -274, + 0 + ], + [ + -274, + 119.90000000000009 + ], + [ + -348, + 119.90000000000009 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -274, + 0 + ], + "end": [ + -274, + 119.90000000000009 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4279, + "versionNonce": 655398818, + "index": "bA2", + "isDeleted": false, + "id": "yTndQFGb2OqrLkDZ9DALY", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 2699.9, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 240, + "seed": 362246178, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uXRCx2XGVmAnC2YOkC7Zi", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "endBinding": { + "elementId": "yP4erX1fWBumj9BpqXX-9", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -254, + 0 + ], + [ + -254, + 240 + ], + [ + -348, + 240 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -254, + 0 + ], + "end": [ + -254, + 240 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5187, + "versionNonce": 1377067582, + "index": "bA3", + "isDeleted": true, + "id": "DIvEv8X-DzJRWI58Nr1f5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -2400.0000000000005, + "y": 2860, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.32175889652489786, + "height": 147.99999999999977, + "seed": 1397250686, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774258673748, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.32175889652489786, + 147.99999999999977 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5323, + "versionNonce": 706827106, + "index": "bA4", + "isDeleted": false, + "id": "5EHGV6fnCwaYVGpRMfIFi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8800, + "y": 2760, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.4178823304036996, + "height": 201.87837236703854, + "seed": 1583744930, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "inside", + "fixedPoint": [ + 0.49850756310570105, + 0.013416945478847232 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.4178823304036996, + 201.87837236703854 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 4348, + "versionNonce": 1260689186, + "index": "bA5", + "isDeleted": false, + "id": "7vZ-YT-Ga_VtUw0r2p184", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8654, + "y": 2680, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 119.90000000000009, + "seed": 282010914, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "uXRCx2XGVmAnC2YOkC7Zi", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.3333333333333333 + ] + }, + "endBinding": { + "elementId": "L5B-OI8bZQ3Yh8VovmqDH", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 274, + 0 + ], + [ + 274, + 119.90000000000009 + ], + [ + 348, + 119.90000000000009 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 274, + 0 + ], + "end": [ + 274, + 119.90000000000009 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4652, + "versionNonce": 982082274, + "index": "bA6", + "isDeleted": false, + "id": "BLYoQHoxrsYAunwIS-qxX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8654, + "y": 3020, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 80.09999999999991, + "seed": 1672788222, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.4285714285714285 + ] + }, + "endBinding": { + "elementId": "jdBXqVXuHDIqseYY5ec03", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 274, + 0 + ], + [ + 274, + -80.09999999999991 + ], + [ + 348, + -80.09999999999991 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 274, + 0 + ], + "end": [ + 274, + -80.09999999999991 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4952, + "versionNonce": 1201960098, + "index": "bA7", + "isDeleted": false, + "id": "CEYL0u8W-q6hARVJiuXqx", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8654, + "y": 3060, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 388, + "height": 479.9000000000001, + "seed": 1140174114, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096904, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.7142857142857142 + ] + }, + "endBinding": { + "elementId": "aLxODB5MmtDLve4n-s97h", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 254, + 0 + ], + [ + 254, + 479.9000000000001 + ], + [ + 388, + 479.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 254, + 0 + ], + "end": [ + 254, + 479.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4940, + "versionNonce": 647703522, + "index": "bA8", + "isDeleted": true, + "id": "tPSC9e8DyQIG4N1-eh1zb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 3926, + "y": 2393.3333333333335, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 388, + "height": 360, + "seed": 1137521406, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774258887727, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.6666666666666666 + ] + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 40, + 0 + ], + [ + 40, + -13.333333333333485 + ], + [ + 388, + -13.333333333333485 + ], + [ + 388, + 346.6666666666665 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 3, + "start": [ + 40, + -13.333333333333485 + ], + "end": [ + 388, + -13.333333333333485 + ] + } + ], + "startIsSpecial": true, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4233, + "versionNonce": 80974434, + "index": "bA9", + "isDeleted": false, + "id": "6vm2-UsZEsH8TJAt2XF91", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8944.77266472711, + "y": 2980.0009987156373, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 349.2273352728894, + "height": 419.89900128436284, + "seed": 743042146, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + -0.017045231168252226, + 0.14286427654026607 + ] + }, + "endBinding": { + "elementId": "BkiR3xiMELGC4ZUdjFozZ", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -315.2273352728894, + 0 + ], + [ + -315.2273352728894, + 419.89900128436284 + ], + [ + -349.2273352728894, + 419.89900128436284 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -315.2273352728894, + 0 + ], + "end": [ + -315.2273352728894, + 419.89900128436284 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4374, + "versionNonce": 859239970, + "index": "bAA", + "isDeleted": false, + "id": "rNzFLDTlFrKhXD8I-DWym", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 3000, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 539.9000000000001, + "seed": 1652073214, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.28571428571428564 + ] + }, + "endBinding": { + "elementId": "CpeSKlNPHRLoaq3jsfuxr", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -294, + 0 + ], + [ + -294, + 539.9000000000001 + ], + [ + -348, + 539.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -294, + 0 + ], + "end": [ + -294, + 539.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4453, + "versionNonce": 1324868066, + "index": "bAB", + "isDeleted": false, + "id": "KDj_pySRY-a4_6AtuSH9K", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 3020, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 348, + "height": 659.9000000000001, + "seed": 1442317246, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.4285714285714285 + ] + }, + "endBinding": { + "elementId": "aizFvR-aD6OZ5iyPOCgBH", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -274, + 0 + ], + [ + -274, + 659.9000000000001 + ], + [ + -348, + 659.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -274, + 0 + ], + "end": [ + -274, + 659.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4899, + "versionNonce": 1663391138, + "index": "bAC", + "isDeleted": false, + "id": "d9ivtAVmxoRVCNaIBclhv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8654, + "y": 3040, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 388, + "height": 359.9000000000001, + "seed": 938618046, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.5714285714285713 + ] + }, + "endBinding": { + "elementId": "ItloWTyf24bCMkzBZL3Zn", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 274, + 0 + ], + [ + 274, + 359.9000000000001 + ], + [ + 388, + 359.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 274, + 0 + ], + "end": [ + 274, + 359.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4866, + "versionNonce": 1089360226, + "index": "bAD", + "isDeleted": false, + "id": "LKKDODOY8WCuSLN0fqIhB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 3040, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 114, + "height": 639.9000000000001, + "seed": 771182754, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.5714285714285713 + ] + }, + "endBinding": { + "elementId": "u0xFgjkYZAVJkZajG0-lO", + "mode": "orbit", + "fixedPoint": [ + -0.02142857142857143, + 0.49916666666666737 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -114, + 0 + ], + [ + -114, + 639.9000000000001 + ], + [ + 0, + 639.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -114, + 0 + ], + "end": [ + -114, + 639.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4797, + "versionNonce": 1000461602, + "index": "bAE", + "isDeleted": false, + "id": "AXRKzYQWEPTZMrEbSnFXg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8946, + "y": 3060, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 94, + "height": 481.9000000000001, + "seed": 1782902654, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "30x4AZdPbcjjkhJ9_d2zt", + "mode": "orbit", + "fixedPoint": [ + -0.016666666666666666, + 0.4991935483870975 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -94, + 0 + ], + [ + -94, + 481.9000000000001 + ], + [ + -40, + 481.9000000000001 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -94, + 0 + ], + "end": [ + -94, + 481.9000000000001 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4915, + "versionNonce": 1689182434, + "index": "bAF", + "isDeleted": false, + "id": "zmQa1myT7Zv9BqPrG2Rc7", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -8944.772664727112, + "y": 3079.9990012843623, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 75.22733527288892, + "height": 321.9009987156378, + "seed": 1486226238, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774259096780, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QP2swWZwKIUNmJFMsKa9F", + "mode": "orbit", + "fixedPoint": [ + -0.01704523116825385, + 0.8571357234597305 + ] + }, + "endBinding": { + "elementId": "831lZwuEF8HMkL7hx6Npp", + "mode": "orbit", + "fixedPoint": [ + -0.016666666666666666, + 0.4991935483870975 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -75.22733527288892, + 0 + ], + [ + -75.22733527288892, + 321.9009987156378 + ], + [ + -41.22733527288892, + 321.9009987156378 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + -75.22733527288892, + 0 + ], + "end": [ + -75.22733527288892, + 321.9009987156378 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "rectangle", + "version": 2979, + "versionNonce": 1905746942, + "index": "bAG", + "isDeleted": false, + "id": "bQMOyq7ZLrZkL5zugTIKI", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -700, + "y": 1400, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1800, + "height": 1700, + "seed": 1629647870, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3177, + "versionNonce": 2068198462, + "index": "bAH", + "isDeleted": false, + "id": "cORVVUgT8bJMgeFIy50yW", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1300, + "y": 2640, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 560, + "height": 460.0000000000001, + "seed": 1876303266, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3242, + "versionNonce": 1060174974, + "index": "bAI", + "isDeleted": false, + "id": "wta-fYic28C3tFCogle2O", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1300, + "y": 1720, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 560, + "height": 880, + "seed": 1803582, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3197, + "versionNonce": 51952830, + "index": "bAJ", + "isDeleted": false, + "id": "hdus37FdbrcQ_jWozQzeb", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1300, + "y": 1260, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 560, + "height": 420.00000000000017, + "seed": 15709374, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1329, + "versionNonce": 748582142, + "index": "bAK", + "isDeleted": false, + "id": "wAWLyaK8h7tvITmQoX0ga", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1100, + "y": 1280, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 130.47994995117188, + "height": 37.800000000000004, + "seed": 2130843170, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Developer", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Developer", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1366, + "versionNonce": 1162028350, + "index": "bAL", + "isDeleted": false, + "id": "ddHbKsUOw3bPASoRUFrQW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1080, + "y": 1740, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 90.71994018554688, + "height": 37.800000000000004, + "seed": 280198078, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "GitHub", + "textAlign": "left", + "verticalAlign": "middle", + "containerId": null, + "originalText": "GitHub", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1432, + "versionNonce": 2120732030, + "index": "bAM", + "isDeleted": false, + "id": "k1USPa9Nmws0uFPtVyt6V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1100, + "y": 2660, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 157.3118896484375, + "height": 37.800000000000004, + "seed": 1276417662, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Monitoring", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Monitoring", + "autoResize": false, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1528, + "versionNonce": 894266814, + "index": "bAN", + "isDeleted": false, + "id": "TfO1Efgit5FWsfGqif44F", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -220, + "y": 1420, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 799.9999999999999, + "height": 37.800000000000004, + "seed": 2091518882, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Platform - GCP / Digital Ocean", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Cloud Platform - GCP / Digital Ocean", + "autoResize": false, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3491, + "versionNonce": 1997866494, + "index": "bAO", + "isDeleted": false, + "id": "yqA37Uk9PnoWmAEad6oNf", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1080, + "y": 1800, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1550019390, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "KnuT7JgfILN4mSTre1RRv" + }, + { + "id": "HGE0-3wwJRUSEeq92cbJN", + "type": "arrow" + }, + { + "id": "xxZhLwfEwjuO6htM3X1yF", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3718, + "versionNonce": 79664702, + "index": "bAP", + "isDeleted": false, + "id": "KnuT7JgfILN4mSTre1RRv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1008.4179534912109, + "y": 1841.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 136.83590698242188, + "height": 37.800000000000004, + "seed": 361714558, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Repository", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "yqA37Uk9PnoWmAEad6oNf", + "originalText": "Repository", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3508, + "versionNonce": 1462640254, + "index": "bAQ", + "isDeleted": false, + "id": "804D0Y2HM0hY6k8hhoYws", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1080, + "y": 1980, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 1790114878, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "oxz5XdappZIQenRt1_3OG" + }, + { + "id": "xxZhLwfEwjuO6htM3X1yF", + "type": "arrow" + }, + { + "id": "0kL8E5YAof2VlYoSVD2HL", + "type": "arrow" + }, + { + "id": "9cGxnK2GdoFMtEqGHR4sC", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3768, + "versionNonce": 589405886, + "index": "bAR", + "isDeleted": false, + "id": "oxz5XdappZIQenRt1_3OG", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1036.7819290161133, + "y": 2002.1999999999998, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 193.56385803222656, + "height": 75.60000000000001, + "seed": 902087806, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "GitHub Actions\nCI/CD", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "804D0Y2HM0hY6k8hhoYws", + "originalText": "GitHub Actions\nCI/CD", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3507, + "versionNonce": 1564153598, + "index": "bAS", + "isDeleted": false, + "id": "zo1Jh7eZ5nHFiSZDOVCRs", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1240, + "y": 2380, + "strokeColor": "#ffffff", + "backgroundColor": "#17c4b7", + "width": 280, + "height": 120.00000000000001, + "seed": 96905982, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "qvKjiIb99gpNAuY6GUDtN" + }, + { + "id": "0kL8E5YAof2VlYoSVD2HL", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3800, + "versionNonce": 1039894334, + "index": "bAT", + "isDeleted": false, + "id": "qvKjiIb99gpNAuY6GUDtN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1213.3859176635742, + "y": 2421.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 226.77183532714844, + "height": 37.800000000000004, + "seed": 2012519230, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Container registry", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "zo1Jh7eZ5nHFiSZDOVCRs", + "originalText": "Container registry", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3513, + "versionNonce": 1170468734, + "index": "bAU", + "isDeleted": false, + "id": "-ttVdpo2MwverPP8fJhDe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1160, + "y": 1400, + "strokeColor": "#ffffff", + "backgroundColor": "#a18072", + "width": 280, + "height": 120.00000000000001, + "seed": 128812798, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "c1CF4m4qc4PDy5iltrd_w" + }, + { + "id": "HGE0-3wwJRUSEeq92cbJN", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3750, + "versionNonce": 1087721406, + "index": "bAV", + "isDeleted": false, + "id": "c1CF4m4qc4PDy5iltrd_w", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1099.7019653320312, + "y": 1441.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 159.4039306640625, + "height": 37.800000000000004, + "seed": 1352660798, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Code + Push", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-ttVdpo2MwverPP8fJhDe", + "originalText": "Code + Push", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3234, + "versionNonce": 1263577086, + "index": "bAW", + "isDeleted": false, + "id": "88a-j0OhV34BfKO9J3I41", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 280, + "y": 2640, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 780.0000000000001, + "height": 420.0000000000001, + "seed": 2077321534, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3284, + "versionNonce": 1429665854, + "index": "bAX", + "isDeleted": false, + "id": "SqTsa4tgJV05iRAMSfQxu", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -660, + "y": 2640, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 899.9999999999999, + "height": 420.00000000000006, + "seed": 766370338, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 3543, + "versionNonce": 644431998, + "index": "bAY", + "isDeleted": false, + "id": "NWvUo9v1IpBkVa6YltZqb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1240, + "y": 2920, + "strokeColor": "#ffffff", + "backgroundColor": "#228be6", + "width": 280, + "height": 120.00000000000001, + "seed": 922939326, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "GvRAyfFawcmYa-3evtcsi" + }, + { + "id": "T3u9Q6G_QdIf7vobYbPOq", + "type": "arrow" + }, + { + "id": "Ov9VXA2F2UoSvzPfogM6j", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3839, + "versionNonce": 1655210174, + "index": "bAZ", + "isDeleted": false, + "id": "GvRAyfFawcmYa-3evtcsi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1141.9159774780273, + "y": 2961.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 83.83195495605469, + "height": 37.800000000000004, + "seed": 1791641598, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Sentry", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NWvUo9v1IpBkVa6YltZqb", + "originalText": "Sentry", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3554, + "versionNonce": 227916030, + "index": "bAa", + "isDeleted": false, + "id": "bFcfU0GF43VRrlQcKx9MZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1240, + "y": 2760, + "strokeColor": "#ffffff", + "backgroundColor": "#228be6", + "width": 280, + "height": 120.00000000000001, + "seed": 1513432318, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "LTjRJsQS7ePWYWdj6jwew" + }, + { + "id": "6rGf8oTCiv8m4yyalXIrx", + "type": "arrow" + }, + { + "id": "-y8XPwDNLP2DbYZrro139", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3869, + "versionNonce": 246540606, + "index": "bAb", + "isDeleted": false, + "id": "LTjRJsQS7ePWYWdj6jwew", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1192.7639465332031, + "y": 2801.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 185.52789306640625, + "height": 37.800000000000004, + "seed": 1820579134, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Logging", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bFcfU0GF43VRrlQcKx9MZ", + "originalText": "Cloud Logging", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3588, + "versionNonce": 895357310, + "index": "bAc", + "isDeleted": false, + "id": "OimqY9g909iIy9ydN4DDO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 360, + "y": 2820, + "strokeColor": "#ffffff", + "backgroundColor": "#7950f2", + "width": 280, + "height": 120.00000000000001, + "seed": 1050439358, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "48uySMlDuhgzh3WAyAygo" + }, + { + "id": "OV9Jq-1tIBuAuUcJl7Sc4", + "type": "arrow" + }, + { + "id": "8pJDcxuFn8LiWz7w4y-3f", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3921, + "versionNonce": 1020998078, + "index": "bAd", + "isDeleted": false, + "id": "48uySMlDuhgzh3WAyAygo", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 400.4320526123047, + "y": 2861.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 199.13589477539062, + "height": 37.800000000000004, + "seed": 1625024254, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Secret Manager", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OimqY9g909iIy9ydN4DDO", + "originalText": "Secret Manager", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3604, + "versionNonce": 1347045886, + "index": "bAe", + "isDeleted": false, + "id": "z781Yjnu9AxXWyQ4Xa7m4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 700, + "y": 2820, + "strokeColor": "#ffffff", + "backgroundColor": "#7950f2", + "width": 280, + "height": 120.00000000000001, + "seed": 2088653474, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "SF477G5ekPPLUGRhoY2VK" + }, + { + "id": "QpBnmRjFlFriFy1X_H55M", + "type": "arrow" + }, + { + "id": "QcEvkSmmNZod43AdzGuY1", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3961, + "versionNonce": 246176318, + "index": "bAf", + "isDeleted": false, + "id": "SF477G5ekPPLUGRhoY2VK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 741.4400482177734, + "y": 2842.2, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 197.11990356445312, + "height": 75.60000000000001, + "seed": 538947170, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Cloud Storage /\nSpaces", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "z781Yjnu9AxXWyQ4Xa7m4", + "originalText": "Cloud Storage / Spaces", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1469, + "versionNonce": 249717374, + "index": "bAg", + "isDeleted": false, + "id": "JizPh0FGiX5lZIfTrdlFR", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -300, + "y": 2660, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 157.3118896484375, + "height": 37.800000000000004, + "seed": 379026594, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Data", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Data", + "autoResize": false, + "lineHeight": 1.35 + }, + { + "type": "text", + "version": 1494, + "versionNonce": 1672307390, + "index": "bAh", + "isDeleted": false, + "id": "WPfG5tUV_-o11m10dnb0x", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 580, + "y": 2660, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 157.3118896484375, + "height": 37.800000000000004, + "seed": 1802788578, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Storage", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Storage", + "autoResize": false, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3628, + "versionNonce": 531520254, + "index": "bAi", + "isDeleted": false, + "id": "Dl7LTqGyq4aHLvK2AKTb1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -640, + "y": 2800, + "strokeColor": "#ffffff", + "backgroundColor": "#12b886", + "width": 200, + "height": 160.00000000000003, + "seed": 1364280382, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "QErn1v2CZu6VlTHBlj6Js" + }, + { + "id": "gS0C64mGU-ftwNd9h1qZF", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3967, + "versionNonce": 1499876158, + "index": "bAj", + "isDeleted": false, + "id": "QErn1v2CZu6VlTHBlj6Js", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -598.3379898071289, + "y": 2861.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 116.67597961425781, + "height": 37.800000000000004, + "seed": 1096420478, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "DB - Dev", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Dl7LTqGyq4aHLvK2AKTb1", + "originalText": "DB - Dev", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3637, + "versionNonce": 792081278, + "index": "bAk", + "isDeleted": false, + "id": "hFsF2felkBLX3I7brhV1T", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -420, + "y": 2800, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 200, + "height": 160.00000000000003, + "seed": 2128380542, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "h8pehlyARc1EXGVtFOOaZ" + }, + { + "id": "H_55ALNlRNX-hpCesgyPF", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3983, + "versionNonce": 1264522174, + "index": "bAl", + "isDeleted": false, + "id": "h8pehlyARc1EXGVtFOOaZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -383.0979766845703, + "y": 2861.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 126.19595336914062, + "height": 37.800000000000004, + "seed": 258179774, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "DB - Prod", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "hFsF2felkBLX3I7brhV1T", + "originalText": "DB - Prod", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3648, + "versionNonce": 1744956414, + "index": "bAm", + "isDeleted": false, + "id": "iJzKFXcqEAWtSyPMFKbFr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -200, + "y": 2800, + "strokeColor": "#ffffff", + "backgroundColor": "#12b886", + "width": 200, + "height": 160.00000000000003, + "seed": 135048482, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "SAU4b6VjCYiqaWjN1jtiM" + }, + { + "id": "pU4SPq-CM3PEkK_As2C84", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4007, + "versionNonce": 1394588734, + "index": "bAn", + "isDeleted": false, + "id": "SAU4b6VjCYiqaWjN1jtiM", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -173.40196990966797, + "y": 2861.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 146.80393981933594, + "height": 37.800000000000004, + "seed": 234797282, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Redis - Dev", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "iJzKFXcqEAWtSyPMFKbFr", + "originalText": "Redis - Dev", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3659, + "versionNonce": 1922663550, + "index": "bAo", + "isDeleted": false, + "id": "FmXtBVnBzVKR3Dd4ZBGA4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 20, + "y": 2800, + "strokeColor": "#ffffff", + "backgroundColor": "#fa5252", + "width": 200, + "height": 160.00000000000003, + "seed": 15663870, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "2eWqdSHvIl2rWqc1FpXyJ" + }, + { + "id": "wDbi91cfpyb_eT-ibUVZk", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4023, + "versionNonce": 1211122878, + "index": "bAp", + "isDeleted": false, + "id": "2eWqdSHvIl2rWqc1FpXyJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 41.838043212890625, + "y": 2861.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 156.32391357421875, + "height": 37.800000000000004, + "seed": 475132734, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Redis - Prod", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "FmXtBVnBzVKR3Dd4ZBGA4", + "originalText": "Redis - Prod", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3578, + "versionNonce": 1971649790, + "index": "bAq", + "isDeleted": false, + "id": "u6yhKpGgHpm5eqjg0lPhZ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -360, + "y": 2180, + "strokeColor": "#ffffff", + "backgroundColor": "#40c057", + "width": 280, + "height": 120.00000000000001, + "seed": 1946686270, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "6fZ93i66NGiP8Am9pW3JK" + }, + { + "id": "5OkMYQD6L2_dQk8tRvv7x", + "type": "arrow" + }, + { + "id": "9cGxnK2GdoFMtEqGHR4sC", + "type": "arrow" + }, + { + "id": "6rGf8oTCiv8m4yyalXIrx", + "type": "arrow" + }, + { + "id": "QpBnmRjFlFriFy1X_H55M", + "type": "arrow" + }, + { + "id": "QcEvkSmmNZod43AdzGuY1", + "type": "arrow" + }, + { + "id": "8pJDcxuFn8LiWz7w4y-3f", + "type": "arrow" + }, + { + "id": "pU4SPq-CM3PEkK_As2C84", + "type": "arrow" + }, + { + "id": "gS0C64mGU-ftwNd9h1qZF", + "type": "arrow" + }, + { + "id": "Ov9VXA2F2UoSvzPfogM6j", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3837, + "versionNonce": 1075359038, + "index": "bAr", + "isDeleted": false, + "id": "6fZ93i66NGiP8Am9pW3JK", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -271.5899887084961, + "y": 2221.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 103.17997741699219, + "height": 37.800000000000004, + "seed": 576650110, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "API Dev", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "u6yhKpGgHpm5eqjg0lPhZ", + "originalText": "API Dev", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3611, + "versionNonce": 357324158, + "index": "bAs", + "isDeleted": false, + "id": "dpojJBfrLIAdS9y-btvPb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 440, + "y": 2180, + "strokeColor": "#ffffff", + "backgroundColor": "#fc1d32", + "width": 280, + "height": 120.00000000000001, + "seed": 1140979682, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "uCjrUneN6QaWfMUaEdRK-" + }, + { + "id": "wbWhcOXxBWP4YYa88Qmh1", + "type": "arrow" + }, + { + "id": "e1wG-JiuTKiq38nmCJ8jC", + "type": "arrow" + }, + { + "id": "-y8XPwDNLP2DbYZrro139", + "type": "arrow" + }, + { + "id": "T3u9Q6G_QdIf7vobYbPOq", + "type": "arrow" + }, + { + "id": "QpBnmRjFlFriFy1X_H55M", + "type": "arrow" + }, + { + "id": "OV9Jq-1tIBuAuUcJl7Sc4", + "type": "arrow" + }, + { + "id": "H_55ALNlRNX-hpCesgyPF", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3879, + "versionNonce": 241235390, + "index": "bAt", + "isDeleted": false, + "id": "uCjrUneN6QaWfMUaEdRK-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 523.6500244140625, + "y": 2221.1, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 112.699951171875, + "height": 37.800000000000004, + "seed": 444378018, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "API Prod", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dpojJBfrLIAdS9y-btvPb", + "originalText": "API Prod", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "rectangle", + "version": 3606, + "versionNonce": 1953992190, + "index": "bAu", + "isDeleted": false, + "id": "NXvDLPz0jPcP9Y5e1IxxH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -40, + "y": 1680, + "strokeColor": "#ffffff", + "backgroundColor": "#ff5f00", + "width": 400, + "height": 120.00000000000001, + "seed": 2125709986, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "tuADBu306XQ_2AV9jrVhi" + }, + { + "id": "wbWhcOXxBWP4YYa88Qmh1", + "type": "arrow" + }, + { + "id": "5OkMYQD6L2_dQk8tRvv7x", + "type": "arrow" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3906, + "versionNonce": 1150361150, + "index": "bAv", + "isDeleted": false, + "id": "tuADBu306XQ_2AV9jrVhi", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 56.23206329345703, + "y": 1702.1999999999998, + "strokeColor": "#ffffff", + "backgroundColor": "transparent", + "width": 207.53587341308594, + "height": 75.60000000000001, + "seed": 438771298, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Load Balancer\nSSL Termination", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NXvDLPz0jPcP9Y5e1IxxH", + "originalText": "Load Balancer\nSSL Termination", + "autoResize": true, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 5461, + "versionNonce": 864986750, + "index": "bAw", + "isDeleted": false, + "id": "HGE0-3wwJRUSEeq92cbJN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -939.9838424944421, + "y": 1526, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.011583169746302246, + "height": 267.99999999999955, + "seed": 882056638, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "-ttVdpo2MwverPP8fJhDe", + "mode": "orbit", + "fixedPoint": [ + 0.7857671960443523, + 0.7911328036103024 + ] + }, + "endBinding": { + "elementId": "yqA37Uk9PnoWmAEad6oNf", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0.011583169746302246, + 267.99999999999955 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "arrow", + "version": 5571, + "versionNonce": 842081982, + "index": "bAx", + "isDeleted": false, + "id": "xxZhLwfEwjuO6htM3X1yF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -939.972, + "y": 1926, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0, + "height": 48, + "seed": 1527304958, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "yqA37Uk9PnoWmAEad6oNf", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0.9999999999999999 + ] + }, + "endBinding": { + "elementId": "804D0Y2HM0hY6k8hhoYws", + "mode": "orbit", + "fixedPoint": [ + 0.5001, + 0 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 48 + ] + ], + "elbowed": false, + "moveMidPointsWithElement": false + }, + { + "type": "rectangle", + "version": 3360, + "versionNonce": 1897504510, + "index": "bAy", + "isDeleted": false, + "id": "PN4g-4Cc-6bt8ATcqVwwU", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -660, + "y": 2020, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1720, + "height": 460.00000000000006, + "seed": 160402722, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1547, + "versionNonce": 1690898238, + "index": "bAz", + "isDeleted": false, + "id": "10XyOkyaztZLB8Ge1tmxC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 80, + "y": 2040, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 157.3118896484375, + "height": 37.800000000000004, + "seed": 2143232510, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 6, + "text": "Compute", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Compute", + "autoResize": false, + "lineHeight": 1.35 + }, + { + "type": "arrow", + "version": 4018, + "versionNonce": 1235253118, + "index": "bB0", + "isDeleted": false, + "id": "wbWhcOXxBWP4YYa88Qmh1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 260, + "y": 1806, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 260, + "height": 368, + "seed": 1717297214, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "NXvDLPz0jPcP9Y5e1IxxH", + "mode": "orbit", + "fixedPoint": [ + 0.75, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.2857142857142857, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 94 + ], + [ + 260, + 94 + ], + [ + 260, + 368 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 94 + ], + "end": [ + 260, + 94 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4047, + "versionNonce": 669046718, + "index": "bB1", + "isDeleted": false, + "id": "5OkMYQD6L2_dQk8tRvv7x", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 60, + "y": 1806, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 280.0999999999999, + "height": 368, + "seed": 167952354, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "NXvDLPz0jPcP9Y5e1IxxH", + "mode": "orbit", + "fixedPoint": [ + 0.25, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.49964285714285744, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 94 + ], + [ + -280.0999999999999, + 94 + ], + [ + -280.0999999999999, + 368 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 94 + ], + "end": [ + -280.0999999999999, + 94 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4225, + "versionNonce": 1470836734, + "index": "bB2", + "isDeleted": false, + "id": "0kL8E5YAof2VlYoSVD2HL", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -1040, + "y": 2106, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 140, + "height": 268, + "seed": 1453526846, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "tg5r3vJlN_KGF7ADlYxI3" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "804D0Y2HM0hY6k8hhoYws", + "mode": "orbit", + "fixedPoint": [ + 0.14285714285714285, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "zo1Jh7eZ5nHFiSZDOVCRs", + "mode": "orbit", + "fixedPoint": [ + 0.21428571428571427, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 108 + ], + [ + -140, + 108 + ], + [ + -140, + 268 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 108 + ], + "end": [ + -140, + 108 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "id": "tg5r3vJlN_KGF7ADlYxI3", + "type": "text", + "x": 148.28204345703125, + "y": 2696.5, + "width": 163.4359130859375, + "height": 35, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#12b886", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "bB2V", + "roundness": null, + "seed": 416537378, + "version": 14, + "versionNonce": 1728337826, + "isDeleted": false, + "boundElements": null, + "updated": 1774270480218, + "link": null, + "locked": false, + "text": "Build & Push", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0kL8E5YAof2VlYoSVD2HL", + "originalText": "Build & Push", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "RSpF18ZEc2RNWjuwciKQW", + "type": "text", + "x": 226.34600067138672, + "y": 2696.5, + "width": 7.3079986572265625, + "height": 35, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#12b886", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "bB3", + "roundness": null, + "seed": 943855970, + "version": 3, + "versionNonce": 843601598, + "isDeleted": true, + "boundElements": null, + "updated": 1774270474430, + "link": null, + "locked": false, + "text": "", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0kL8E5YAof2VlYoSVD2HL", + "originalText": "", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 4280, + "versionNonce": 83918910, + "index": "bB4", + "isDeleted": false, + "id": "9cGxnK2GdoFMtEqGHR4sC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -940.1, + "y": 2106, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 660.1, + "height": 68, + "seed": 1499117090, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "pjANVjzkkvLTXynMXtLuE" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "804D0Y2HM0hY6k8hhoYws", + "mode": "orbit", + "fixedPoint": [ + 0.49964285714285706, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.2857142857142857, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 34 + ], + [ + 660.1, + 34 + ], + [ + 660.1, + 68 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 34 + ], + "end": [ + 660.1, + 34 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "id": "pjANVjzkkvLTXynMXtLuE", + "type": "text", + "x": 684.6880142211915, + "y": 2622.5, + "width": 90.52397155761719, + "height": 35, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#12b886", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "bB5", + "roundness": null, + "seed": 1934850238, + "version": 8, + "versionNonce": 1608538814, + "isDeleted": false, + "boundElements": null, + "updated": 1774270513093, + "link": null, + "locked": false, + "text": "Deploy", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "9cGxnK2GdoFMtEqGHR4sC", + "originalText": "Deploy", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 4401, + "versionNonce": 868337790, + "index": "bB6", + "isDeleted": false, + "id": "e1wG-JiuTKiq38nmCJ8jC", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -840, + "y": 2106, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1340, + "height": 68, + "seed": 223994878, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "8m4EgqP94I9CdkX3WYnIC" + } + ], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.21428571428571427, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 14 + ], + [ + 1340, + 14 + ], + [ + 1340, + 68 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 14 + ], + "end": [ + 1340, + 14 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "id": "8m4EgqP94I9CdkX3WYnIC", + "type": "text", + "x": 724.7880142211914, + "y": 2616.5, + "width": 90.52397155761719, + "height": 35, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#12b886", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "bB7", + "roundness": null, + "seed": 2058925118, + "version": 12, + "versionNonce": 218265122, + "isDeleted": false, + "boundElements": [], + "updated": 1774270516109, + "link": null, + "locked": false, + "text": "Deploy", + "fontSize": 28, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "e1wG-JiuTKiq38nmCJ8jC", + "originalText": "Deploy", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 4283, + "versionNonce": 1135610046, + "index": "bB8", + "isDeleted": false, + "id": "6rGf8oTCiv8m4yyalXIrx", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -339.9979796323139, + "y": 2305.117756897121, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 614.0020203676861, + "height": 494.8822431028789, + "seed": 292337058, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.07143578702745036, + 1.042647974142676 + ] + }, + "endBinding": { + "elementId": "bFcfU0GF43VRrlQcKx9MZ", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.3333333333333333 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 74.88224310287887 + ], + [ + -574.0020203676861, + 74.88224310287887 + ], + [ + -574.0020203676861, + 494.8822431028789 + ], + [ + -614.0020203676861, + 494.8822431028789 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 74.88224310287887 + ], + "end": [ + -574.0020203676861, + 74.88224310287887 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4596, + "versionNonce": 1953251582, + "index": "bB9", + "isDeleted": false, + "id": "Ov9VXA2F2UoSvzPfogM6j", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -300, + "y": 2306, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 654, + "height": 654, + "seed": 804323774, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.21428571428571427, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "NWvUo9v1IpBkVa6YltZqb", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.3333333333333333 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 94 + ], + [ + -600, + 94 + ], + [ + -600, + 654 + ], + [ + -654, + 654 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 94 + ], + "end": [ + -600, + 94 + ] + }, + { + "index": 3, + "start": [ + -600, + 94 + ], + "end": [ + -600, + 654 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4549, + "versionNonce": 1769435454, + "index": "bBA", + "isDeleted": false, + "id": "-y8XPwDNLP2DbYZrro139", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 460.0020203676859, + "y": 2305.1177568971216, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 1414.0020203676859, + "height": 534.8822431028784, + "seed": 902197154, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.07143578702744954, + 1.0426479741426797 + ] + }, + "endBinding": { + "elementId": "bFcfU0GF43VRrlQcKx9MZ", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.6666666666666666 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 114.88224310287842 + ], + [ + -1340.0020203676859, + 114.88224310287842 + ], + [ + -1340.0020203676859, + 534.8822431028784 + ], + [ + -1414.0020203676859, + 534.8822431028784 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 114.88224310287842 + ], + "end": [ + -1340.0020203676859, + 114.88224310287842 + ] + }, + { + "index": 3, + "start": [ + -1340.0020203676859, + 114.88224310287842 + ], + "end": [ + -1340.0020203676859, + 534.8822431028784 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4875, + "versionNonce": 775068030, + "index": "bBB", + "isDeleted": false, + "id": "T3u9Q6G_QdIf7vobYbPOq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 500, + "y": 2306, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 1454, + "height": 694, + "seed": 1958600766, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.21428571428571427, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "NWvUo9v1IpBkVa6YltZqb", + "mode": "orbit", + "fixedPoint": [ + 1.0214285714285714, + 0.6666666666666666 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 134 + ], + [ + -1360, + 134 + ], + [ + -1360, + 694 + ], + [ + -1454, + 694 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 134 + ], + "end": [ + -1360, + 134 + ] + }, + { + "index": 3, + "start": [ + -1360, + 134 + ], + "end": [ + -1360, + 694 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5174, + "versionNonce": 970897854, + "index": "bBC", + "isDeleted": false, + "id": "QpBnmRjFlFriFy1X_H55M", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 699.9979796323141, + "y": 2305.1177568971216, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 120.00202036768587, + "height": 508.8822431028784, + "seed": 1098451518, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.9285642129725504, + 1.0426479741426797 + ] + }, + "endBinding": { + "elementId": "z781Yjnu9AxXWyQ4Xa7m4", + "mode": "orbit", + "fixedPoint": [ + 0.42857142857142855, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 74.88224310287842 + ], + [ + 120.00202036768587, + 74.88224310287842 + ], + [ + 120.00202036768587, + 508.8822431028784 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 74.88224310287842 + ], + "end": [ + 120.00202036768587, + 74.88224310287842 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5223, + "versionNonce": 1939657214, + "index": "bBD", + "isDeleted": false, + "id": "OV9Jq-1tIBuAuUcJl7Sc4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 660, + "y": 2306, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 100, + "height": 508, + "seed": 80508962, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.7857142857142857, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "OimqY9g909iIy9ydN4DDO", + "mode": "orbit", + "fixedPoint": [ + 0.7142857142857143, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 74 + ], + [ + -100, + 74 + ], + [ + -100, + 508 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 74 + ], + "end": [ + -100, + 74 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5348, + "versionNonce": 913171006, + "index": "bBE", + "isDeleted": false, + "id": "wDbi91cfpyb_eT-ibUVZk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 620, + "y": 2306, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 500.0999999999999, + "height": 488, + "seed": 1398233278, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "FmXtBVnBzVKR3Dd4ZBGA4", + "mode": "orbit", + "fixedPoint": [ + 0.49950000000000044, + -0.03749999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 194 + ], + [ + -500.0999999999999, + 194 + ], + [ + -500.0999999999999, + 488 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 194 + ], + "end": [ + -500.0999999999999, + 194 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5562, + "versionNonce": 1429400190, + "index": "bBF", + "isDeleted": false, + "id": "H_55ALNlRNX-hpCesgyPF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 540, + "y": 2306, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 860.1, + "height": 488, + "seed": 1098443938, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "dpojJBfrLIAdS9y-btvPb", + "mode": "orbit", + "fixedPoint": [ + 0.35714285714285715, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "hFsF2felkBLX3I7brhV1T", + "mode": "orbit", + "fixedPoint": [ + 0.4994999999999999, + -0.03749999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 154 + ], + [ + -860.1, + 154 + ], + [ + -860.1, + 488 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 154 + ], + "end": [ + -860.1, + 154 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 4814, + "versionNonce": 514648766, + "index": "bBG", + "isDeleted": false, + "id": "QcEvkSmmNZod43AdzGuY1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -100.0020203676861, + "y": 2305.1177568971216, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 900.0020203676861, + "height": 508.8822431028784, + "seed": 1646568034, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.9285642129725497, + 1.0426479741426797 + ] + }, + "endBinding": { + "elementId": "z781Yjnu9AxXWyQ4Xa7m4", + "mode": "orbit", + "fixedPoint": [ + 0.35714285714285715, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 254.88224310287842 + ], + [ + 900.0020203676861, + 254.88224310287842 + ], + [ + 900.0020203676861, + 508.8822431028784 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + }, + { + "type": "arrow", + "version": 4921, + "versionNonce": 1635574526, + "index": "bBH", + "isDeleted": false, + "id": "8pJDcxuFn8LiWz7w4y-3f", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -140, + "y": 2306, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 580, + "height": 508, + "seed": 1273446206, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.7857142857142857, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "OimqY9g909iIy9ydN4DDO", + "mode": "orbit", + "fixedPoint": [ + 0.2857142857142857, + -0.049999999999999996 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 274 + ], + [ + 580, + 274 + ], + [ + 580, + 508 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 274 + ], + "end": [ + 580, + 274 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5007, + "versionNonce": 1881396030, + "index": "bBI", + "isDeleted": false, + "id": "pU4SPq-CM3PEkK_As2C84", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -180, + "y": 2306, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 79.90000000000032, + "height": 488, + "seed": 379836798, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.6428571428571429, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "iJzKFXcqEAWtSyPMFKbFr", + "mode": "orbit", + "fixedPoint": [ + 0.4995000000000016, + -0.03749999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 288 + ], + [ + 79.90000000000032, + 288 + ], + [ + 79.90000000000032, + 488 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 288 + ], + "end": [ + 79.90000000000032, + 288 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "type": "arrow", + "version": 5217, + "versionNonce": 620936062, + "index": "bBJ", + "isDeleted": false, + "id": "gS0C64mGU-ftwNd9h1qZF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": -260, + "y": 2306, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "width": 280.1, + "height": 488, + "seed": 821434814, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1774271105051, + "link": null, + "locked": false, + "startBinding": { + "elementId": "u6yhKpGgHpm5eqjg0lPhZ", + "mode": "orbit", + "fixedPoint": [ + 0.35714285714285715, + 1.0499999999999998 + ] + }, + "endBinding": { + "elementId": "Dl7LTqGyq4aHLvK2AKTb1", + "mode": "orbit", + "fixedPoint": [ + 0.4994999999999999, + -0.03749999999999999 + ] + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 0, + 294 + ], + [ + -280.1, + 294 + ], + [ + -280.1, + 488 + ] + ], + "elbowed": true, + "moveMidPointsWithElement": false, + "fixedSegments": [ + { + "index": 2, + "start": [ + 0, + 294 + ], + "end": [ + -280.1, + 294 + ] + } + ], + "startIsSpecial": false, + "endIsSpecial": false + }, + { + "id": "shZ-VkdgTWnWyTO4wNgUW", + "type": "arrow", + "x": 1800, + "y": 2987, + "width": 659, + "height": 124, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "#12b886", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "bBK", + "roundness": null, + "seed": 52110590, + "version": 19, + "versionNonce": 1282682082, + "isDeleted": true, + "boundElements": null, + "updated": 1774270953260, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 37 + ], + [ + 628.5, + 37 + ], + [ + 628.5, + -87 + ], + [ + 659, + -87 + ] + ], + "startBinding": { + "elementId": "PN4g-4Cc-6bt8ATcqVwwU", + "mode": "orbit", + "fixedPoint": [ + 0.6511627906976745, + 1.0152173913043476 + ] + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true, + "fixedSegments": null, + "startIsSpecial": null, + "endIsSpecial": null + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": true, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index e08506db..ed0ebe5c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -95,6 +95,7 @@ nav: - Pull Request Guidelines: teams/fullstack/development/10_pull_request_guidelines.md - Code Review Process: teams/fullstack/development/20_code_review_process.md - Project Setup: teams/fullstack/development/30_project_setup.md + - Technical Ownership: teams/fullstack/development/40_project_ownership.md - Tech Stack: - Frontend: teams/fullstack/tech_stack/00_frontend.md - Backend: teams/fullstack/tech_stack/10_backend.md @@ -110,10 +111,12 @@ nav: - Development Environment: - Local Setup: teams/fullstack/dev_env/00_local_setup.md - Secrets: teams/fullstack/dev_env/10_secrets.md + - AI-Assisted Development: teams/fullstack/dev_env/20_ai_tools.md - Deployment: - Process: teams/fullstack/deployment/00_deployment.md - Rollback: teams/fullstack/deployment/10_rollback.md - Monitoring: teams/fullstack/deployment/20_monitoring.md + - Operations: teams/fullstack/deployment/30_ops.md - Documentation: - Code Documentation: teams/fullstack/docs/00_code_docs.md - API Documentation: teams/fullstack/docs/10_api_docs.md @@ -162,7 +165,11 @@ markdown_extensions: - attr_list - md_in_html - pymdownx.details - - pymdownx.superfences + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format - pymdownx.tabbed: alternate_style: true - pymdownx.blocks.caption