Skip to content
Open
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
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|---|---|
| `timeless-api/` | Java 21 / Quarkus 3 backend + Angular 19 frontend (served via Quinoa) |
| `whatsapp/` | Node.js service that bridges WhatsApp messages to the API via SQS |
| `docker/` | Local-dev docker-compose (LocalStack SQS/S3, PostgreSQL, Ollama) |
| `docker/` | Local-dev docker-compose (floci for SQS/S3, PostgreSQL, Ollama) |
| `infrastructure/` | Terraform / AWS provisioning |
| `site/` | Landing page |

Expand Down Expand Up @@ -52,7 +52,7 @@ npm run prettier:write # format check + apply
### Local infrastructure

```bash
cd docker && docker-compose up -d # starts LocalStack + PostgreSQL (Ollama excluded by default)
cd docker && docker-compose up -d # starts floci (LocalStack replacement) + PostgreSQL (Ollama excluded by default)

# Include the local Ollama container (opt-in via the "ollama" compose profile)
cd docker && docker-compose --profile ollama up -d
Expand Down Expand Up @@ -119,7 +119,7 @@ All Java code lives under `dev.matheuscruz` with three layers:
| Profile | Activated by | Key behavior |
|---|---|---|
| `dev` (default) | `quarkus:dev` | Uses OpenAI, requires `OPENAI_API_KEY` in `application.properties` |
| `local` | `-Dquarkus.profile=local` | Uses Ollama at `localhost:11434`, uses LocalStack for SQS |
| `local` | `-Dquarkus.profile=local` | Uses Ollama at `localhost:11434`, uses floci (local AWS emulator) for SQS |
| `test` | `@QuarkusTest` | Disables SQS devservices, disables OpenAI integration, disables scheduler |

Maven profiles `openai` (active by default) and `ollama` control which LangChain4j dependency is included. Use `-Pollama` to switch.
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ We love community contributions! Whether you're fixing a bug or adding a feature

If you want to use Terraform and AWS see [this tutorial](RUNNING_TERRAFORM_AWS.md).

## Running locally with localstack
## Running locally with floci (local AWS emulator)

> [!WARNING]
> Actually, you will need two phones and a OpenAI token. Feel free to change the code to support only one number and a local LLM.
Expand All @@ -69,7 +69,8 @@ If you want to use Terraform and AWS see [this tutorial](RUNNING_TERRAFORM_AWS.m
docker-compose up -d
```

This starts LocalStack and PostgreSQL only. The Ollama container is now opt-in
This starts [floci](https://github.com/floci-io/floci) (a free, open-source LocalStack
replacement that emulates SQS and S3 on port 4566) and PostgreSQL only. The Ollama container is now opt-in
via the `ollama` Compose profile — include it only if you plan to run the API
against a local LLM without Quarkus Dev Services:

Expand Down
22 changes: 13 additions & 9 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
version: '3.8'

services:
localstack:
image: localstack/localstack:4.2.0
container_name: localstack
floci:
# Drop-in replacement for LocalStack (https://github.com/floci-io/floci).
# The "-compat" variant bundles the AWS CLI so scripts/init.sh can seed queues and buckets.
image: floci/floci:latest-compat
container_name: floci
ports:
- "4566:4566"
environment:
- SERVICES=sqs,s3
- DEBUG=1
- DATA_DIR=/var/lib/localstack/data
# keep queues/buckets across restarts (in-memory + async flush to disk every 5s)
- FLOCI_STORAGE_MODE=hybrid
volumes:
- ./localstack-data:/var/lib/localstack/data
# named volume: the image owns /app/data as uid 1001, a bind mount would be root-owned
- floci-data:/app/data
- ./scripts:/etc/localstack/init/ready.d
- /var/run/docker.sock:/var/run/docker.sock

postgres:
image: postgres:17
Expand All @@ -33,4 +34,7 @@ services:
profiles:
- ollama
ports:
- "11434:11434"
- "11434:11434"

volumes:
floci-data:
12 changes: 9 additions & 3 deletions docker/scripts/init.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/bin/bash
# Seeds the local AWS emulator (floci) with the resources the app expects.
# Runs on container start; safe to re-run because state is persisted between restarts.
set -u

awslocal sqs create-queue --queue-name incoming-message.fifo --attributes '{"FifoQueue": "True"}'
awslocal sqs create-queue --queue-name recognized-message.fifo --attributes '{"FifoQueue": "True"}'
ENDPOINT="http://localhost:4566"

awslocal s3 mb s3://timeless-local-assets
aws --endpoint-url "$ENDPOINT" sqs create-queue --queue-name incoming-message.fifo --attributes '{"FifoQueue": "True"}'
aws --endpoint-url "$ENDPOINT" sqs create-queue --queue-name recognized-message.fifo --attributes '{"FifoQueue": "True"}'

aws --endpoint-url "$ENDPOINT" s3api head-bucket --bucket timeless-local-assets 2>/dev/null \
|| aws --endpoint-url "$ENDPOINT" s3 mb s3://timeless-local-assets
15 changes: 8 additions & 7 deletions timeless-api/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ mp.jwt.verify.issuer=https://timelessapp.platformoon.com/issuer
smallrye.jwt.new-token.issuer=https://timelessapp.platformoon.com/issuer


# dev profile - ./mvnw quarkus:dev : OpenAI plus LocalStack
# dev profile - ./mvnw quarkus:dev : OpenAI plus floci (local AWS emulator)

%dev.security.sensible.secret=YS0xNi1ieXRlLXNlY3JldA==

# sqs to localstack
# sqs to floci (local AWS emulator on port 4566)
%dev.mp.messaging.incoming.whatsapp-incoming.region=us-east-1
%dev.mp.messaging.incoming.whatsapp-incoming.endpoint-override=http://localhost:4566
%dev.quarkus.sqs.endpoint-override=http://localhost:4566
Expand All @@ -56,9 +56,9 @@ smallrye.jwt.new-token.issuer=https://timelessapp.platformoon.com/issuer
%dev.quarkus.hibernate-orm.log.sql=true


# local profile - ./mvnw quarkus:dev -Pollama -Dquarkus.profile=local : Ollama plus LocalStack
# local profile - ./mvnw quarkus:dev -Pollama -Dquarkus.profile=local : Ollama plus floci (local AWS emulator)

# sqs to localstack
# sqs to floci (local AWS emulator on port 4566)
%local.mp.messaging.incoming.whatsapp-incoming.region=us-east-1
%local.mp.messaging.incoming.whatsapp-incoming.endpoint-override=http://localhost:4566
%local.quarkus.sqs.endpoint-override=http://localhost:4566
Expand All @@ -84,15 +84,16 @@ smallrye.jwt.new-token.issuer=https://timelessapp.platformoon.com/issuer
%test.whatsapp.incoming-message.queue-url=test-incoming-queue
%test.whatsapp.recognized-message.queue-url=test-processed-queue

# sqs to localstack
# sqs to floci (local AWS emulator on port 4566)
%test.quarkus.sqs.endpoint-override=http://127.0.0.1:4566
%test.quarkus.sqs.aws.region=us-east-1
%test.quarkus.sqs.aws.credentials.type=STATIC
%test.quarkus.sqs.aws.credentials.static-provider.access-key-id=test
%test.quarkus.sqs.aws.credentials.static-provider.secret-access-key=test

# jwt
%test.mp.jwt.verify.publickey=test-public-key
# jwt bundled dev keys under src/main/resources so tests can sign and verify tokens
%test.mp.jwt.verify.publickey.location=publicKey.pem
%test.smallrye.jwt.sign.key.location=privateKey.pem

# disable background integrations during tests
%test.quarkus.scheduler.enabled=false
Expand Down
Loading