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
7 changes: 7 additions & 0 deletions apps/database/meowbotdb/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM postgres:17.4

ENV POSTGRES_USER=default_user
ENV POSTGRES_PASSWORD=default_password
ENV POSTGRES_DB=meowbot

COPY apps/database/meowbotdb/src/ /docker-entrypoint-initdb.d/
127 changes: 127 additions & 0 deletions apps/database/meowbotdb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# MeowbotDB

![Build](https://img.shields.io/github/actions/workflow/status/dotablaze-tech/platform/ci.yml?branch=main)
![Docker Image Version](https://img.shields.io/docker/v/dotablaze/meowbotdb)
![Docker Image Size](https://img.shields.io/docker/image-size/dotablaze/meowbotdb)
![Docker Downloads](https://img.shields.io/docker/pulls/dotablaze/meowbotdb?label=downloads)
![Nx](https://img.shields.io/badge/Nx-managed-blue)

**MeowbotDB** is the PostgreSQL database service used by Meowbot — a multi-server Discord bot for community interaction, reactions, and playful engagement. It provides the schema and seed data required for bot state, logs, preferences, and other persistent features.

This service is containerized and managed via [Nx](https://nx.dev), supporting multi-arch Docker builds and local development with optional volume caching.

---

## 📁 Project Structure

```text
database/meowbotdb/
├── Dockerfile # Defines the Postgres image and entrypoint
├── project.json # Nx configuration and targets
└── src/
├── 00_schema.sql # SQL schema definitions for bot state and logs
└── 01_data.sql # Initial data (e.g., test configs, emoji presets)
```

---

## 🚀 Getting Started

### Prerequisites

- Docker
- [Nx CLI](https://nx.dev)

### Run Locally (Ephemeral)

```bash
nx run meowbotdb:serve
```

Runs PostgreSQL in a disposable Docker container on port `5432`.

### Run with Persistent Volume

```bash
nx run meowbotdb:serve-cache
```

Creates and mounts a Docker volume (`meowbotdb-data`) for persistent local storage.

### Clear Persistent Volume

```bash
nx run meowbotdb:clear-cache
```

Removes the `meowbotdb-data` volume to reset local database state.

---

## 🔨 Build

Build Docker images with semantic versioning and multi-platform support.

### CI/CD Multi-Arch Build

```bash
nx run meowbotdb:build-image
```

Builds and pushes images for `linux/amd64` and `linux/arm64`, tagged as `latest` and with semantic version.

### Local Build Only

```bash
nx run meowbotdb:local-build-image
```

Builds a local image using host architecture for development/testing.

---

## 🗃️ Database Credentials

Default credentials after container start:

```text
Host: localhost
Port: 5432
Database: meowbot
User: default_user
Password: default_password
```

---

## 📄 SQL Files

- `00_schema.sql` – Table definitions, indexes, relationships
- `01_data.sql` – Seed data for dev/testing (emojis, preferences, etc.)

These scripts are executed automatically at container start.

---

## 🧪 Versioning

Handled via [Conventional Commits](https://www.conventionalcommits.org/) + [`@jscutlery/semver`](https://github.com/jscutlery/semver):

```bash
nx run meowbotdb:version
```

Automates version bumping, changelog, tagging, and build/push.

---

## 📦 Deployment

Used internally by Meowbot services across environments, including CI pipelines and local dev.

---

## 📌 Notes

- This is a purpose-built, stateful service for Discord bot functionality.
- Migration tooling is not currently integrated — for production schema evolution, consider [Flyway](https://flywaydb.org/) or [Sqitch](https://sqitch.org/).
50 changes: 50 additions & 0 deletions apps/database/meowbotdb/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "meowbotdb",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "apps/database/meowbotdb/src",
"tags": ["type:app", "language:postgresql", "scope:meowbotdb"],
"targets": {
"version": {
"executor": "@jscutlery/semver:version",
"options": {
"push": true,
"preset": "conventionalcommits",
"postTargets": ["build-image"]
}
},
"build-image": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "docker buildx build --platform linux/amd64,linux/arm64 -f {projectRoot}/Dockerfile -t dotablaze/meowbotdb:latest -t dotablaze/meowbotdb:{version} --push .",
"forwardAllArgs": false
}
],
"parallel": false
}
},
"local-build-image": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "docker buildx build -f {projectRoot}/Dockerfile -t dotablaze/meowbotdb:latest .",
"forwardAllArgs": false
}
],
"parallel": false
}
},
"serve": {
"command": "docker run --rm -p 5432:5432 dotablaze/meowbotdb:latest"
},
"serve-cache": {
"command": "docker run --rm -v meowbotdb-data:/var/lib/postgresql/data -p 5432:5432 dotablaze/meowbotdb:latest"
},
"clear-cache": {
"command": "docker volume rm meowbotdb-data || true"
}
}
}
47 changes: 47 additions & 0 deletions apps/database/meowbotdb/src/00_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
-- CREATE DATABASE meowbot;

CREATE TABLE guilds
(
id TEXT PRIMARY KEY,
created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE users
(
id TEXT PRIMARY KEY,
username TEXT,
created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE user_guild_stats
(
guild_id TEXT REFERENCES guilds (id) ON DELETE CASCADE,
user_id TEXT REFERENCES users (id) ON DELETE CASCADE,
successful_meows INT DEFAULT 0,
failed_meows INT DEFAULT 0,
total_meows INT DEFAULT 0,
current_streak INT DEFAULT 0,
highest_streak INT DEFAULT 0,
last_meow_at TIMESTAMP,
last_failed_meow_at TIMESTAMP,
PRIMARY KEY (guild_id, user_id)
);

CREATE INDEX idx_user_guild_stats_user_id ON user_guild_stats (user_id);
CREATE INDEX idx_user_guild_stats_guild_id ON user_guild_stats (guild_id);

CREATE TABLE guild_streaks
(
guild_id TEXT PRIMARY KEY REFERENCES guilds (id) ON DELETE CASCADE,
meow_count INT DEFAULT 0,
last_user_id TEXT,
high_score INT DEFAULT 0,
high_score_user_id TEXT
);

CREATE TABLE IF NOT EXISTS guild_channels
(
guild_id TEXT PRIMARY KEY,
channel_id TEXT NOT NULL
);

1 change: 1 addition & 0 deletions apps/database/meowbotdb/src/01_data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

4 changes: 2 additions & 2 deletions apps/go/meowbot/Dockerfile.local
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Remember to check for updates to base images to incorporate security patches
# Use a specific version of golang based on SHA256 digest for reproducibility and security
FROM golang:1.23 AS builder-go
FROM golang:1.24 AS builder-go

# Use a specific version of node base on SHA256 digest for reproducibility and security
FROM node:lts-alpine AS builder
WORKDIR /app

ARG GOLANG_VERSION=1.23
ARG GOLANG_VERSION=1.24
COPY --from=builder-go /usr/local/go /usr/local/go
ENV PATH=$PATH:/usr/local/go/bin

Expand Down
11 changes: 5 additions & 6 deletions apps/go/meowbot/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# 🐾 Meow Bot

![Docker](https://img.shields.io/docker/pulls/jdwillmsen/meow-bot?label=downloads)
![Docker Image Version](https://img.shields.io/docker/v/jdwillmsen/jdw-servicediscovery)
![Docker Image Size](https://img.shields.io/docker/image-size/jdwillmsen/jdw-servicediscovery)
![Docker Downloads](https://img.shields.io/docker/pulls/jdwillmsen/jdw-servicediscovery?label=downloads)
![Build](https://img.shields.io/github/actions/workflow/status/dotablaze-tech/platform/ci.yml?branch=main)
![Docker Image Version](https://img.shields.io/docker/v/dotablaze/meowbot)
![Docker Image Size](https://img.shields.io/docker/image-size/dotablaze/meowbot)
![Docker Downloads](https://img.shields.io/docker/pulls/dotablaze/meowbot?label=downloads)
![Nx](https://img.shields.io/badge/Nx-managed-blue)
![License](https://img.shields.io/github/license/jdwillmsen/jdw)

**Meow Bot** is a lightweight and fun Discord bot built with Go and powered by `discordgo`. It tracks consecutive “meow”
messages in a single channel, maintaining streaks, preventing duplicate users, and celebrating high scores. Ideal for
Expand Down Expand Up @@ -34,7 +33,7 @@ apps/go/meow-bot/

### Prerequisites

- Go 1.23+
- Go 1.24+
- [Nx CLI](https://nx.dev)
- Docker (optional for containerized runs)
- Discord bot token
Expand Down
8 changes: 4 additions & 4 deletions apps/go/meowbot/go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module apps/go/meowbot

go 1.23
go 1.24

require github.com/bwmarrin/discordgo v0.28.1

require (
github.com/gorilla/websocket v1.4.2 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/sys v0.32.0 // indirect
)
9 changes: 6 additions & 3 deletions apps/go/meowbot/go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4=
github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Loading