Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
3a6b259
feat: Protect home page with Angular Guards
matheusandre1 Dec 11, 2025
df71259
feat: allow to edit personal data (#136)
matheusandre1 Dec 12, 2025
ded6237
chore(deps-dev): bump postcss in /timeless-api/src/main/webui (#147)
dependabot[bot] Dec 12, 2025
8d4d254
ci: generate OCI Images (#121)
matheusandre1 Dec 13, 2025
5d96fad
ci: change working dir
mcruzdev Dec 13, 2025
e306111
ci: adjust pipeline
mcruzdev Dec 13, 2025
6cf02af
ci: mvn inline
mcruzdev Dec 13, 2025
a0f3d54
ci: use docker
mcruzdev Dec 13, 2025
526fd45
ci: configure sock
mcruzdev Dec 13, 2025
5e627c4
fix: fix ci
mcruzdev Dec 13, 2025
5c9a163
ci: add tcp
mcruzdev Dec 13, 2025
23247ac
fix: fix docker host
mcruzdev Dec 13, 2025
b29a3c9
ci: remove publish
mcruzdev Dec 13, 2025
9c070f2
ci: use podman
mcruzdev Dec 13, 2025
628165a
feat: Protect home page with Angular Guards
matheusandre1 Dec 16, 2025
1dce6e4
ci: remove buildpack build manually
mcruzdev Dec 28, 2025
8ee7961
ci(timeless-api): adjust timeless-api
mcruzdev Dec 28, 2025
ccbe1c7
ci(all): apply adjusts
mcruzdev Dec 28, 2025
ef8c529
fix(ci): fix wrong image name
mcruzdev Dec 28, 2025
a533203
ci(chrome): add heroku community buildpack
mcruzdev Dec 28, 2025
e3f9f8b
ci(whatsapp): change image tag
mcruzdev Dec 28, 2025
5c7d8a7
ci(whatsapp): use v5.10.0 instead
mcruzdev Dec 28, 2025
621d1db
ci: use build and pull_request workflows
mcruzdev Dec 28, 2025
0357a0c
ci: add heroku/heroku-buildpack-chrome-for-testing repo
mcruzdev Dec 28, 2025
33ffc2b
ci: use tar.gz file for chrome buildpack
mcruzdev Dec 28, 2025
e98debc
ci: use own buildpack
mcruzdev Dec 28, 2025
8f6587b
ci: use own buildpack
mcruzdev Dec 28, 2025
6294f48
chore(deps-dev): bump autoprefixer in /timeless-api/src/main/webui (#…
dependabot[bot] Dec 28, 2025
07c2b68
chore: change workflow naming
mcruzdev Dec 28, 2025
7c54f64
ci: fix working-directory for allowing permission
mcruzdev Dec 28, 2025
f081def
ci: remove allow permission step
mcruzdev Dec 28, 2025
dd5e506
ci(buildpack): add detect
mcruzdev Dec 28, 2025
25531f6
ci(buildpack): change buildpack id
mcruzdev Dec 28, 2025
0655ca8
ci(whatsapp): change main property
mcruzdev Dec 28, 2025
f4159f6
ci: remove chromium for a moment
mcruzdev Dec 28, 2025
a50c61f
chore(angular): upgrade primeng and angular (#179)
mcruzdev Dec 28, 2025
7b77a6d
ci(whatsapp): disable whatsapp image push
mcruzdev Dec 28, 2025
1e504ae
docs: add project intent
mcruzdev Dec 29, 2025
8a99b3b
docs: remove typo
mcruzdev Dec 29, 2025
78a7cc2
docs: update README.md
mcruzdev Dec 29, 2025
92ec54b
docs: update README.md
mcruzdev Dec 29, 2025
fce2d90
docs: refactor README for clarity and conciseness
mcruzdev Dec 29, 2025
62403a1
feat: Protect home page with Angular Guards
matheusandre1 Dec 11, 2025
9516b6d
feat: Protect home page with Angular Guards
matheusandre1 Dec 16, 2025
6f46613
fix: rename file
matheusandre1 Dec 29, 2025
0af69f6
Merge branch 'feat-issue50' of https://github.com/matheusandre1/timel…
matheusandre1 Dec 29, 2025
a4b4613
feat: Add GitHub Actions CI workflow to build and publish Timeless AP…
matheusandre1 Dec 30, 2025
d97b068
Adjust user config (#184)
mcruzdev Dec 31, 2025
e20a680
feat(site): add contributors (#185)
mcruzdev Dec 31, 2025
79f810c
ci(whatsapp): dockerize whatsapp app (#186)
mcruzdev Dec 31, 2025
74e1c76
fix: allow only query my own data (#126)
mcruzdev Dec 31, 2025
8f11ec4
ci: prepare terraform files (#187)
mcruzdev Jan 1, 2026
816ee58
ci(terraform): add queue name as variable
mcruzdev Jan 1, 2026
589858f
refactor: adjust environment variables
mcruzdev Jan 1, 2026
42cb3ee
feat: add condition when ENV is production
mcruzdev Jan 1, 2026
b98ac2b
chore: change quarkus property naming
mcruzdev Jan 1, 2026
b57e22c
feat: log queues
mcruzdev Jan 1, 2026
461a99f
refactor: apply code style
mcruzdev Jan 1, 2026
f42e8d6
feat: send qrcode to S3 when the ENV is production
mcruzdev Jan 1, 2026
e15e559
fix: remove Resend dependency
mcruzdev Jan 1, 2026
02da4eb
chore: add smallrye-health
mcruzdev Jan 1, 2026
c7a40a5
fix: move quinoa build to dis/timeless/browser
mcruzdev Jan 1, 2026
3fa53ff
chore: configure jwt properties
mcruzdev Jan 1, 2026
f25340f
fix(security): delete api key
mcruzdev Jan 1, 2026
a63f9cd
chore: apply prettier --write
mcruzdev Jan 1, 2026
345b97d
feat: Protect home page with Angular Guards
matheusandre1 Dec 11, 2025
0df1da0
feat: Protect home page with Angular Guards
matheusandre1 Dec 16, 2025
acb0cfd
fix: rename file
matheusandre1 Dec 29, 2025
5c1f0ee
feat: Protect home page with Angular Guards
matheusandre1 Dec 11, 2025
de992bd
feat: Protect home page with Angular Guards
matheusandre1 Dec 16, 2025
6c05f7b
Merge branch 'feat-issue50' of https://github.com/matheusandre1/timel…
matheusandre1 Jan 3, 2026
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
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ updates:
commit-message:
prefix: chore
include: scope
allow:
- dependency-type: direct

- package-ecosystem: maven
directory: /timeless-api
Expand All @@ -32,3 +34,5 @@ updates:
commit-message:
prefix: chore
include: scope
allow:
- dependency-type: direct
120 changes: 120 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Timeless CI - Build & Publish

on:
push:
branches: [ "main" ]
paths-ignore:
- 'infrastructure/**'
pull_request:
branches: [ "main" ]
paths-ignore:
- 'infrastructure/**'

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
timeless-api:
name: Build & Publish - Timeless API (Java)
runs-on: ubuntu-latest
defaults:
run:
working-directory: timeless-api

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
cache: maven

- name: Build API
run: mvn -B -ntp formatter:validate impsort:check package

- name: Setup Node.js 24
uses: actions/setup-node@v4
with:
node-version: "24"
cache: npm
cache-dependency-path: timeless-api/src/main/webui/package-lock.json

- name: Setup Chrome
id: chrome
uses: browser-actions/setup-chrome@v1

- name: Install Frontend Dependencies
working-directory: ./timeless-api/src/main/webui
run: npm ci

- name: Check code formatting with Prettier
working-directory: ./timeless-api/src/main/webui
run: npm run prettier:check

- name: Set up Podman
uses: gacts/install-podman@v1
if: github.repository == 'mcruzdev/timeless'
id: podman

- name: Login to Quay.io
if: github.repository == 'mcruzdev/timeless'
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

- name: Create Docker image
if: github.repository == 'mcruzdev/timeless'
run: docker build -f src/main/docker/Dockerfile.jvm -t quay.io/timeless/timeless-api:${GITHUB_SHA::7} .

- name: Push Docker image to Quay.io
if: github.repository == 'mcruzdev/timeless'
run: docker push quay.io/timeless/timeless-api:${GITHUB_SHA::7}

whatsapp:
name: Build & Publish - WhatsApp Bot (Node.js)
runs-on: ubuntu-latest
defaults:
run:
working-directory: whatsapp

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: whatsapp/package-lock.json

- name: Install dependencies
run: npm ci

- name: Check code formatting with Prettier
run: npm run prettier:check

- name: Login to Quay.io
if: github.repository == 'mcruzdev/timeless'
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}

- name: Create Docker image
if: github.repository == 'mcruzdev/timeless'
run: docker build -f Dockerfile -t quay.io/timeless/whatsapp:${GITHUB_SHA::7} .

- name: Push Docker image to Quay.io
if: github.repository == 'mcruzdev/timeless'
run: docker push quay.io/timeless/whatsapp:${GITHUB_SHA::7}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Timeless CI
name: Timeless CI - Pull Request Build

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
paths-ignore:
- 'infrastructure/**'

permissions:
contents: read
Expand All @@ -15,11 +15,11 @@ concurrency:

jobs:
timeless-api:
name: Build & Test - Timeless API (Java)
name: Build Timeless API (Backend)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./timeless-api
working-directory: timeless-api

steps:
- name: Checkout
Expand All @@ -32,13 +32,20 @@ jobs:
java-version: "21"
cache: maven

- name: Setup Node.js 20
- name: Build Timeless API
run: mvn -B -ntp formatter:validate impsort:check package

- name: Setup Node.js 24
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "24"
cache: npm
cache-dependency-path: timeless-api/src/main/webui/package-lock.json

- name: Check code formatting with Prettier
working-directory: ./timeless-api/src/main/webui
run: npm run prettier:check

- name: Setup Chrome
id: chrome
uses: browser-actions/setup-chrome@v1
Expand All @@ -47,40 +54,26 @@ jobs:
working-directory: ./timeless-api/src/main/webui
run: npm ci

- name: Check code formatting with Prettier
working-directory: ./timeless-api/src/main/webui
run: npm run prettier:check

- name: Ensure Maven wrapper is executable
run: chmod +x mvnw

- name: Build with unit and integration tests
run: ./mvnw -B -ntp formatter:validate impsort:check package
env:
CHROME_BIN: ${{ steps.chrome.outputs.chrome-path }}

whatsapp:
name: Lint - WhatsApp
name: Build WhatsApp Bot (Node.js)
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./whatsapp
working-directory: whatsapp

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Node.js 20
- name: Setup Node.js 24
uses: actions/setup-node@v4
with:
node-version: "20"
node-version: "24"
cache: npm
cache-dependency-path: whatsapp/package-lock.json

- name: Install Dependencies
run: npm ci

- name: Check code formatting with Prettier
run: npm run prettier:check


run: npm run prettier:check
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ See our landing page: [**https://timeless.platformoon.com**](https://timeless.pl

This application monitors WhatsApp messages for signs of purchases (such as receipts, audio messages, transfers), extracts relevant information (amounts, descriptions), and automatically sends it to **Timeless**, helping you keep your finances organized — effortlessly.

## ⚠️ Project Intent

Timeless is primarily an educational project built to explore the intersection of automated messaging, NLP, and cloud infrastructure. While it mimics real-world financial tracking systems, its core goal is to demonstrate:

* **Production-like Architecture**: Integrating Java/Quarkus with AI and external messaging APIs.
* **Continuous Improvement**: The codebase is designed to evolve. We encourage experiments with local LLMs and different cloud providers.
* **Learning by Doing**: This is a sandbox for implementing "real-world" logic in a controlled environment. Feel free to refactor, break, and improve!

## 🚀 Features

- 📩 Automatic reading of WhatsApp messages
Expand Down Expand Up @@ -69,7 +77,7 @@ docker-compose up -d
### Execute the whatsapp application

> [!NOTE]
> Before you start, make sure to fill the `ALLOWED_USERS` and `OPENAI_API_KEY` variables in the `.env.local` file. This variable determines the number of users who can interact with the bot.
> Before you start, make sure to fill the `ALLOWED_PHONE_NUMBERS` and `OPENAI_API_KEY` variables in the `.env.local` file. This variable determines the number of users who can interact with the bot.

1. Go to `whatsapp` directory and install all necessary packages:

Expand Down Expand Up @@ -98,4 +106,4 @@ You should receive something like it:

### How to contribute

[CONTRIBUTING.md](CONTRIBUTING.md)
[CONTRIBUTING.md](CONTRIBUTING.md)
12 changes: 6 additions & 6 deletions RUNNING_TERRAFORM_AWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ AWS_SECRET_ACCESS_KEY=
OPENAI_API_KEY=
SECURITY_KEY=
INCOMING_MESSAGE_FIFO_URL=
MESSAGES_PROCESSED_FIFO_URL=
RECOGNIZED_MESSAGES_FIFO_URL=
EOF
```

Expand All @@ -73,7 +73,7 @@ The table below explains the purpose of each variable along with suggested examp
| `OPENAI_API_KEY` | Your OpenAI API key | `sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
| `SECURITY_KEY` | Secret key used for AES encryption (must be exactly 16, 24, or 32 characters long, no accents) | `MySuperSecretAESKey12345678901234` |
| `INCOMING_MESSAGE_FIFO_URL` | The URL of the SQS FIFO queue for incoming messages | `https://sqs.us-east-1.amazonaws.com/123456789/incoming-messages.fifo` |
| `MESSAGES_PROCESSED_FIFO_URL`| The URL of the SQS FIFO queue for processed messages | `https://sqs.us-east-1.amazonaws.com/123456789/messages-processed.fifo` |
| `RECOGNIZED_MESSAGES_FIFO_URL`| The URL of the SQS FIFO queue for processed messages | `https://sqs.us-east-1.amazonaws.com/123456789/messages-processed.fifo` |

4. Execute the application in Dev mode

Expand All @@ -85,7 +85,7 @@ The table below explains the purpose of each variable along with suggested examp

6. Sign in at <http://localhost:8080>

7. Add the user phone number at <http://localhost:8080/home/user-configs>, this phone number must be set after on `ALLOWED_USERS`.
7. Add the user phone number at <http://localhost:8080/home/user-configs>, this phone number must be set after on `ALLOWED_PHONE_NUMBERS`.

## Configuring and running the whatsapp application

Expand All @@ -104,10 +104,10 @@ npm install
| `AWS_ACCESS_KEY_ID` | Your AWS Access Key | `AKIAxxxxxxxxxxxxxxxxxx` |
| `AWS_SECRET_ACCESS_KEY` | Your AWS Secret Key | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
| `ASSETS_BUCKET` | The name of the bucket where audio and images will be stored (created via Terraform) | `my-assets-bucket` |
| `ALLOWED_USERS` | Comma-separated list of phone numbers allowed to interact with the bot | `5511999999999,5511888888888` |
| `ALLOWED_PHONE_NUMBERS` | Comma-separated list of phone numbers allowed to interact with the bot | `5511999999999,5511888888888` |
| `OPENAI_API_KEY` | Your OpenAI API Key used to access GPT and Whisper APIs | `sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
| `INCOMING_MESSAGE_QUEUE` | URL of the SQS queue that receives incoming messages | `https://sqs.us-east-1.amazonaws.com/123456789/incoming-messages.fifo` |
| `MESSAGES_PROCESSED_FIFO_URL`| URL of the SQS FIFO queue where processed messages are sent | `https://sqs.us-east-1.amazonaws.com/123456789/messages-processed.fifo` |
| `RECOGNIZED_MESSAGES_FIFO_URL`| URL of the SQS FIFO queue where processed messages are sent | `https://sqs.us-east-1.amazonaws.com/123456789/messages-processed.fifo` |

4. Start the application

Expand All @@ -127,7 +127,7 @@ npm run start
2. Fill out the registration form with your details and submit it.
3. Log in to your account at [http://localhost:8080](http://localhost:8080).
4. Add your phone number on the [User Configs page](http://localhost:8080/home/user-configs).
⚠️ Make sure the phone number matches one of the values defined in the `ALLOWED_USERS` environment variable.
⚠️ Make sure the phone number matches one of the values defined in the `ALLOWED_PHONE_NUMBERS` environment variable.
5. After connected the device with the scanned QR Code, send the following message: `"Achei mil reais no chão da praia"`.

You should receive something like it:
Expand Down
Loading
Loading