Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 8 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,22 @@
# Product service
## product-service
- **Purpose:** Product catalog (list + detail).
- **Base path:** `/api/products`

## Create product database + user on mysql server
### Create product database
```
kubectl -n cloudshopt exec -it cloudshopt-mysql-0 -- bash

mysql -u root -prootpass
```
# mysql -u root -prootpass

```
CREATE DATABASE cloudshopt_products CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'users'@'%' IDENTIFIED BY 'userspass';
CREATE USER 'users'@'%' IDENTIFIED BY 'CHANGE_ME_PASSWORD';
GRANT ALL PRIVILEGES ON cloudshopt_products.* TO 'users'@'%';
FLUSH PRIVILEGES;
```

Ustvari še bazo za *dev* okolje
```
CREATE DATABASE cloudshopt_products_dev CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'users_dev'@'%' IDENTIFIED BY 'userspass';
GRANT ALL PRIVILEGES ON cloudshopt_products_dev.* TO 'users_dev'@'%';
FLUSH PRIVILEGES;
```

## Crete external secrets for prod and dev
prod:
```
kubectl -n cloudshopt create secret generic product-service-secrets \
--from-literal=DB_PASSWORD="userspass" \
--from-literal=REDIS_PASSWORD="redispass" \
--dry-run=client -o yaml | kubectl apply -f -
```

dev:
```
kubectl -n cloudshopt-dev create secret generic product-service-secrets \
--from-literal=DB_PASSWORD="userspass" \
--from-literal=REDIS_PASSWORD="redispass" \
--dry-run=client -o yaml | kubectl apply -f -
```

check for secrets:
```
kubectl get secret -n cloudshopt product-service-secrets
kubectl get secret -n cloudshopt-dev product-service-secrets
```

## Install product-service for prod and dev
prod:
```
helm upgrade --install product-service ./helm/product-service \
-n cloudshopt \
-f helm/product-service/values.yaml
```

dev:
```
helm upgrade --install product-service-dev ./helm/product-service \
-n cloudshopt-dev \
-f helm/product-service/values-dev.yaml
```

### Migrations


## Migrations

run migrations:
```
kubectl exec -n cloudshopt-dev -it deploy/product-service-dev -c app -- sh

kubectl exec -n cloudshopt -it deploy/product-service -c app -- sh
# php artisan migrate
```
216 changes: 162 additions & 54 deletions docs/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,102 +1,210 @@
openapi: 3.0.3
info:
title: CloudShopt Product Service API
version: 0.1.0
description: API for product catalog
servers:
- url: /api
version: 1.0.0
tags:
- name: meta
- name: products
- name: Health
- name: Diagnostics
- name: Products

paths:
/info:
/healthz:
get:
tags: [meta]
summary: Service info (test endpoint)
tags: [Health]
summary: Health check
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
service:
type: string
example: product-service
status:
type: string
example: ok
$ref: "#/components/schemas/StatusOkBool"

/health:
/info:
get:
tags: [meta]
summary: Health check
tags: [Diagnostics]
summary: Service info (sha, time)
responses:
"200":
description: Healthy
description: Info
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
example: true
$ref: "#/components/schemas/InfoResponse"

/products:
/database:
get:
tags: [products]
summary: List products (test placeholder)
tags: [Diagnostics]
summary: Database connectivity check
responses:
"200":
description: OK
description: DB OK
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/Product"
$ref: "#/components/schemas/DatabaseOkResponse"
"500":
$ref: "#/components/responses/ServerError"
description: DB connection failed
content:
application/json:
schema:
$ref: "#/components/schemas/DatabaseFailResponse"

/items:
get:
tags: [Products]
summary: List products
responses:
"200":
description: Products
content:
application/json:
schema:
$ref: "#/components/schemas/ProductListResponse"

/items/{id}:
get:
tags: [Products]
summary: Get product detail
parameters:
- name: id
in: path
required: true
schema:
type: integer
minimum: 1
responses:
"200":
description: Product
content:
application/json:
schema:
$ref: "#/components/schemas/ProductResponse"
"404":
$ref: "#/components/responses/NotFound"

components:
responses:
ServerError:
description: Server error
NotFound:
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
$ref: "#/components/schemas/ErrorMessage"
example:
message: "Not found"

schemas:
ErrorMessage:
type: object
required: [message]
properties:
message:
type: string

StatusOkBool:
type: object
required: [ok]
properties:
ok:
type: boolean
example: true

InfoResponse:
type: object
required: [ok, service, sha, time]
properties:
ok:
type: boolean
example: true
service:
type: string
example: product-service
sha:
type: string
nullable: true
example: 0.0.1
time:
type: string
format: date-time
example: "2026-01-29T10:15:30.123Z"

DatabaseOkResponse:
type: object
required: [ok, db, time]
properties:
ok:
type: boolean
example: true
db:
type: object
required: [connection, database, ping_ms]
properties:
connection:
type: string
example: mysql
database:
type: string
example: cloudshopt_products_dev
ping_ms:
type: number
format: float
example: 1.25
time:
type: string
format: date-time
example: "2026-01-29T10:15:30.123Z"

DatabaseFailResponse:
type: object
required: [ok, error, message]
properties:
ok:
type: boolean
example: false
error:
type: string
example: DB connection failed
message:
type: string
nullable: true
example: "SQLSTATE[HY000] ..."

Product:
type: object
required: [id, name, price]
properties:
id:
type: integer
example: 1
name:
type: string
example: "T-Shirt"
example: CloudShopt T-Shirt
description:
type: string
nullable: true
example: Basic tee for everyday wear.
price:
type: number
format: float
example: 19.99
type: integer
description: Price in cents
example: 1990
image_url:
type: string
nullable: true
example: null

ErrorResponse:
ProductResponse:
type: object
required: [data]
properties:
message:
type: string
example: "Internal Server Error"
code:
type: string
example: "SERVER_ERROR"
details:
type: object
additionalProperties: true
data:
$ref: "#/components/schemas/Product"

ProductListResponse:
type: object
required: [data]
properties:
data:
type: array
items:
$ref: "#/components/schemas/Product"
2 changes: 1 addition & 1 deletion routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

Route::get('/info', function () {
return response()->json([
'ok11' => true,
'ok' => true,
'service' => config('app.name'),
'sha' => env('IMAGE_SHA', null),
'time' => now()->toISOString(),
Expand Down