{"id":35214539,"url":"https://github.com/m1n64/yii3-stock-api","last_synced_at":"2026-04-21T09:31:45.450Z","repository":{"id":330220857,"uuid":"1121996348","full_name":"m1n64/yii3-stock-api","owner":"m1n64","description":"Yii3-based REST API showcase focused on stock and city domain design","archived":false,"fork":false,"pushed_at":"2025-12-25T00:21:58.000Z","size":2632,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-25T12:58:43.717Z","etag":null,"topics":["backend","clean-architecture","cqrs","openapi","php","postgis","postgresql","rest-api","yii3"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m1n64.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-23T23:27:52.000Z","updated_at":"2025-12-25T00:25:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/m1n64/yii3-stock-api","commit_stats":null,"previous_names":["m1n64/yii3-stock-api"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/m1n64/yii3-stock-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1n64%2Fyii3-stock-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1n64%2Fyii3-stock-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1n64%2Fyii3-stock-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1n64%2Fyii3-stock-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m1n64","download_url":"https://codeload.github.com/m1n64/yii3-stock-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m1n64%2Fyii3-stock-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32085419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T06:27:27.065Z","status":"ssl_error","status_checked_at":"2026-04-21T06:27:21.250Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","clean-architecture","cqrs","openapi","php","postgis","postgresql","rest-api","yii3"],"created_at":"2025-12-29T21:20:36.518Z","updated_at":"2026-04-21T09:31:45.431Z","avatar_url":"https://github.com/m1n64.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stock API Service (Yii3 Showcase)\n\nThis project is a REST API showcase built with **Yii3**.\nIt demonstrates backend architecture, domain design, and infrastructure practices\nusing a simple stock and city domain with location-based features.\n\nThe implementation focuses on clear structure, well-defined layer boundaries,\nand integration of common backend concerns such as persistence, API documentation,\nand observability.\n\nThe project is based on [this technical task](./REST-API-TASK.md).\n\n## 🛠 Tech Stack\n\n- **Runtime**: [FrankenPHP](https://frankenphp.dev/) (PHP 8.4)\n- **Framework**: [Yii3 Framework](https://github.com/yiisoft/app-api) (Beta)\n- **Database**: PostgreSQL + **PostGIS** (for spatial queries)\n- **ORM**: CycleORM (Data Mapper, Proxy support)\n- **Cache**: Redis\n- **Observability**:\n    - **Logs**: Vector + OpenObserve\n    - **Metrics**: InfluxDB + Telegraf + Grafana\n- **Documentation**: OpenAPI (generated) + Stoplight Elements\n\n## 🏗 Architecture\n\nThe project follows a hybrid of **Clean Architecture** and **DDD** principles to ensure maintainability and testability:\n\n- **CQRS \u0026 Command Bus**: All state-changing operations are handled via a strict Command/Handler pattern.\n- **Data Mapper Pattern**: Entities are decoupled from the database schema using CycleORM.\n- **Domain-Driven Design**: Logic is encapsulated within Domain Entities and Services.\n- **Infrastructure Isolation**: External dependencies (Metrics, Logging, Sockets) are abstracted behind interfaces.\n- **Events**: Applied selectively to handle secondary concerns such as cache invalidation.\n\n\u003e **Note**  \n\u003e This architecture emphasizes explicit structure and exploration of Yii3 capabilities.\n\u003e In production systems, architectural complexity is adjusted to project scope,\n\u003e delivery timelines, and team context.\n\n## 🚀 Quick Start\n\n1. **Clone the repository and prepare environment**:\n    ```bash\n    make env-init\n    ```\n\n2. **Spin up the infrastructure (FrankenPHP, DB, Monitoring):**:\n    ```bash\n    make up\n    ```\n\n3. **Run migrations:**\n    ```bash\n    make yii migrate:up \n    ```\n\n## 🧪 Development Commands (not all)\n\n- `make test` — Run all Unit tests (32 tests, 83+ assertions).\n- `make stop` — Stop containers without removing them.\n- `make down` — Shutdown and remove all containers/networks.\n- `make shell` — Open a shell inside the FrankenPHP container.\n- `make yii \u003ccommand\u003e` — Proxy commands directly to the Yii CLI.\n- `make help` — Show all available Makefile commands.\n\n## 🐞 Debugging with Xdebug\n\nThe project is pre-configured for remote debugging with Xdebug 3.5.0+.\n\n1. **PhpStorm configuration**:\n    - **Server Setup**:\n        - Name: `frankenphp`\n        - Host: `localhost`\n        - Port: `80` (or from `./docker/dev/.env`)\n        - Debugger: `Xdebug`\n        - Use path mappings to map project root to `/app` in the container.\n    - Debug Configuration:\n        - Create a new PHP Remote Debug configuration\n        - Set server to `frankenphp`\n        - Set IDE key to `PHPSTORM`\n2. **Activation**:\n    - Install the Xdebug Helper extension in your browser.\n    - Set the IDE Key to `PHPSTORM`.\n    - Click the \"Start Listening for PHP Debug Connections\" icon in PHPStorm.\n\n## 🔗 Project Links\n\n| Resource             | Link                                           | Credits                        |\n|----------------------|------------------------------------------------|--------------------------------|\n| API Endpoint         | [http://localhost/api](http://localhost/api)   | from `.env` for same endpoints |\n| Interactive API Docs | [http://localhost/docs](http://localhost/docs) | -                              |\n| OpenAPI Spec (JSON)  | `./public/openapi.json`                        | -                              |\n| Grafana Dashboards   | [http://localhost:3000](http://localhost:3000) | admin:admin123                 |\n| OpenObserve (Logs)   | [http://localhost:5080](http://localhost:5080) | admin@admin.com:admin123       |\n\n## 🛣 API Endpoints\n\n| Method   | Endpoint                  | Description                       | Auth |\n|----------|---------------------------|-----------------------------------|------|\n| `GET`    | `/api/cities`             | List all cities                   | No   |\n| `GET`    | `/api/cities/{id}`        | Get city details by ID            | No   |\n| `POST`   | `/api/cities`             | Create a new city                 | Yes  |\n| `PATCH`  | `/api/cities/{id}`        | Update city details by ID         | Yes  |\n| `DELETE` | `/api/cities/{id}`        | Delete a city by ID               | Yes  |\n| `GET`    | `/api/cities/{id}/stocks` | List stocks in a specific city    | No   |\n| `GET`    | `/api/stocks`             | List all stocks                   | No   |\n| `GET`    | `/api/stocks/{id}`        | Get stock details by ID           | No   |\n| `POST`   | `/api/stocks`             | Create a new stock                | Yes  |\n| `PATCH`  | `/api/stocks/{id}`        | Update stock details by ID        | Yes  |\n| `DELETE` | `/api/stocks/{id}`        | Delete a stock by ID              | Yes  |\n| `POST`   | `/api/stocks/nearby`      | Find stocks near a given location | No   |\n\nFor detailed request/response schemas, refer to the [Interactive API Docs](http://localhost/docs).\n\n## 💡 Usage Notes\n\n- **Content-Type**: All requests must include Content-Type: `application/json`.\n- **Distributed Tracing**: For better observability, you can optionally send a `Traceparent` header to link requests\n  with `trace_id` in logs and metrics.\n- **Authorization**: Some endpoints require an `Authorization: Bearer \u003ctoken\u003e` header. The token value is configured via\n  `BEARER_TOKEN` in your `.env` file.\n\n## 📸 Project Screenshots\n\n\u003cdetails\u003e \u003csummary\u003e📈 Grafana Metrics Dashboard\u003c/summary\u003e\n\nReal-time monitoring of cache hits, request duration, and system load.\n![img.png](.github/screenshots/grafana-http-server.png)\n![img.png](.github/screenshots/grafana-caddy-server.png)\n![img.png](.github/screenshots/grafana-postgres.png)\n![img.png](.github/screenshots/grafana-redis.png)\n![img.png](.github/screenshots/grafana-system.png)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e \u003csummary\u003e🪵 OpenObserve Logs Viewer\u003c/summary\u003e\n\nStructured logs with `trace_id` and context fields.\n![img.png](.github/screenshots/openobserve-logs.png)\n![img.png](.github/screenshots/openobserve-log.png)\n![img.png](.github/screenshots/openobserve-search.png)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e \u003csummary\u003e📖 Interactive API Documentation (Stoplight)\u003c/summary\u003e\n\nExplore request/response schemas and test endpoints directly.\n![img.png](.github/screenshots/service-api-docs-overview.png)\n![img.png](.github/screenshots/service-api-docs.png)\n![img.png](.github/screenshots/service-api-docs-request.png)\n\n\u003c/details\u003e\n\n## ⚖️ License\n\nThis project is licensed under the [PolyForm Noncommercial License 1.0.0](LICENSE.md).\n\n**Required Notice:** Copyright (c) 2024-2025 Kirill Sakharov (https://github.com/m1n64). All rights reserved.\n\n*Note: This project is built upon the Yii3 Framework, which is licensed under the BSD-3-Clause License.*\n\nCommercial use of this software is strictly prohibited under the terms of the PolyForm license.\n\n### 💡 Engineering Exception \u0026 Disclaimer\n\nI have deep respect for the **dev2dev community** - engineers who build tools for other engineers: framework core\ndevelopers, language contributors, and maintainers of low-level libraries.\n\nDespite the Noncommercial license:\n\n* **Permitted**: You are welcome to study, reference, or adapt architectural patterns and ideas from this\n  repository for use in any **dev-focused** products, core frameworks (like Yii3), or low-level\n  libraries.\n* **Prohibited**: Integration into commercial end-products, \"ready-to-use\" SaaS templates, or redistribution\n  within copyleft-restricted software suites is forbidden due to license incompatibility.\n\n#### Why the restriction?\n\n1. **Beta Status**: Yii3 is currently in its final pre-release stages, and this implementation should be treated as a\n   work-in-progress on a beta-status framework.\n2. **Showcase Only**: This code serves exclusively as a foundation for a technological showcase and\n   architectural review.\n3. **Technical Risks**: Due to the experimental nature of the current stack (Yii3 Beta), this code may contain\n   security or stability vulnerabilities not suitable for production environments.\n\n---\n\n### 🤝 Author's Note\n\nThis project is a personal showcase of modern PHP 8.4 and Yii3 patterns. While not strictly using `form-model` in this\nspecific service, the author is an active contributor to the Yii3 ecosystem (see contributions to\n`yiisoft/form-model`: [#83](https://github.com/yiisoft/form-model/pull/83)\nand [#85](https://github.com/yiisoft/form-model/pull/85)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1n64%2Fyii3-stock-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm1n64%2Fyii3-stock-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm1n64%2Fyii3-stock-api/lists"}