Codync
A free, open-source 1:1 alternative to Grok Bot and Muse. Message Claude Code, Codex, Cursor and 40+ coding agents as persistent bots from your iPhone, Mac or Linux desktop. Group chats, threads, appr
Backend server for MyACT
Translation pending
Developer toolsGitHub @jl1nieOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗MyACTの次世代バックエンドWebサービス
SOTAApp2は、アマチュア無線のアワードプログラム(SOTA、POTA)を管理するための高性能・高可用性Webサービスです。ヘキサゴナルアーキテクチャを採用し、Rustで実装されています。
本システムは**ヘキサゴナルアーキテクチャ(Clean Architecture)**を採用し、以下の6つのレイヤーで構成されています:
┌─────────────────────────────────────────────┐
│ API │ ← RESTエンドポイント・認証・バリデーション
├─────────────────────────────────────────────┤
│ Service │ ← ユースケース・ビジネスロジック
├─────────────────────────────────────────────┤
│ Domain │ ← エンティティ・バリューオブジェクト
├─────────────────────────────────────────────┤
│ Adapter │ ← DB・外部API・APRS・ファイルアクセス
├─────────────────────────────────────────────┤
│ Registry │ ← 依存性注入・モジュール管理
├─────────────────────────────────────────────┤
│ Common │ ← 共通ライブラリ・設定・エラーハンドリング
└─────────────────────────────────────────────┘
api/)service/)UserService: ユーザー向け機能AdminService: 管理者向け機能AdminPeriodicService: バッチ処理・定期実行domain/)Activation: アクティベーション(Alert/Spot)SOTAReference: SOTA山岳データPOTAReference: POTA公園データAprsLog: APRS通信ログadapter/)registry/)common/)| ユースケース | 主要メンテナンス対象 | 変更頻度 | 注意点 |
|---|---|---|---|
| 新機能追加 | Service → API → Domain | 高 | ドメイン変更は慎重に |
| 外部API変更 | Adapter | 中 | インターフェース維持 |
| UI/UX改善 | API(ハンドラー・モデル) | 高 | DTOとドメインの分離 |
| パフォーマンス | Adapter → Service | 中 | N+1問題、キャッシュ |
| セキュリティ | API(認証)→ Common | 低 | 認証・認可ロジック |
| データ移行 | Adapter(migrations) | 低 | スキーマバージョニング |
| 設定変更 | Common | 中 | 環境変数・設定ファイル |
// ✅ 良い例: トレイトによる抽象化
#[async_trait]
pub trait UserService {
async fn find_user(&self, id: UserId) -> AppResult<User>;
}
// ✅ 良い例: 型安全性
pub struct SummitCode(String);
impl SummitCode {
pub fn new(code: String) -> Self {
// バリデーション
Self(code)
}
}
// ❌ 悪い例: 直接的な依存
// Service層からAdapter実装に直接依存
詳細な開発環境構築手順は docs/development-setup.md を参照してください。
git clone https://github.com/jl1nie/sotaapp2.git
cd sotaapp2
cp .env.example .env # 編集してAPIキー等を設定
makers build && makers migrate run && makers run
本番環境: https://sotaapp2.fly.dev
| エンドポイント | 説明 |
|---|---|
GET /api/v2/health | サーバーヘルスチェック |
GET /api/v2/health/db | データベース接続確認 |
| エンドポイント | パラメータ | 説明 |
|---|---|---|
GET /api/v2/activation/alerts | pat_ref (必須) | アラート一覧取得 |
GET /api/v2/activation/spots | pat_ref (必須), hours_ago | スポット一覧取得 |
GET /api/v2/activation/aprs/track | pat_ref (必須), hours_ago | APRSトラック取得 |
パラメータ例:
pat_ref=JA - 日本のアクティベーションpat_ref=JA,HL - 日本と韓国hours_ago=24 - 過去24時間| エンドポイント | 説明 |
|---|---|
GET /api/v2/propagation/geomag | 最新の地磁気指数(A/K指数) |
レスポンス例:
{
"date": "2025-12-26",
"a_index": 12,
"k_index": [3.0, 3.33, 2.67]
}
| エンドポイント | パラメータ | 説明 |
|---|---|---|
GET /api/v2/search | min_lat, max_lat, min_lon, max_lon | 範囲内の山岳・公園検索 |
パラメータ例:
/api/v2/search?min_lat=35&max_lat=36&min_lon=139&max_lon=140
| エンドポイント | パラメータ | 説明 |
|---|---|---|
GET /api/v2/map | lat (必須), lon (必須), zoom, label, tile, embed | 指定座標を中心とした地図をHTMLで表示 |
GET /api/v2/map/view | 同上 | 地図描画に必要な情報をJSONで返す(フロントエンド連携用) |
| パラメータ | 既定値 | 説明 |
|---|---|---|
lat | - | 緯度(-90〜90) |
lon | - | 経度(-180〜180) |
zoom | 15 | ズームレベル(1〜19。タイルの最大ズームに丸められる) |
label | - | マーカーに表示する名称(100文字以内) |
tile | gsi | タイル種別。gsi = 地理院タイル(日本国内のみ)、osm = OpenStreetMap(日本国外はこちら) |
embed | false | trueでヘッダを省略(iframe埋め込み用) |
refs | true | falseで近傍のSOTA山岳・POTA公園の表示を止める |
radius | 1000 | 近傍を探す半径。単位はメートル(1〜10000) |
中心の近く(radius以内)にあるSOTA山岳・POTA公園を、近い順に最大20件マーカーで表示します
(青 = SOTA、緑 = POTA。ポップアップにコード・名称・標高/所在地・距離)。
/api/v2/map/view では nearby 配列として返します。
パラメータ例:
/api/v2/map?lat=35.360556&lon=138.727778&zoom=13&label=富士山&tile=gsi
ブラウザで開くと、指定座標にマーカーを立てた地図(Leaflet)が表示されます。 マーカーのポップアップには座標とグリッドロケータ(メイデンヘッド)が表示されます。
admin/src/lib/api.ts にクライアントヘルパーを用意しています。
import { buildMapUrl, getMapView, hasValidCoordinates } from '$lib/api';
// 1. 別タブで開く / iframeのsrcに指定する
const url = buildMapUrl({ lat, lon, label: summitName });
window.open(url, '_blank', 'noopener');
// 2. iframeに埋め込む(ヘッダ非表示)
const embedUrl = buildMapUrl({ lat, lon, label: summitName, embed: true });
// 3. 自前の地図コンポーネントで描画する
const view = await getMapView({ lat, lon, tile: 'gsi' });
// view.tile.urlTemplate / view.tile.attribution / view.tile.maxZoom を
// Leaflet等にそのまま渡せる。view.externalLinks には外部地図サービスへのリンク。
GET /api/v2/map/view のレスポンス例:
{
"latitude": 35.360556,
"longitude": 138.727778,
"zoom": 15,
"maidenhead": "PM95ii76",
"label": "富士山",
"tile": {
"kind": "gsi",
"urlTemplate": "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
"attribution": "<a href=\"https://maps.gsi.go.jp/development/ichiran.html\">地理院タイル</a>",
"maxZoom": 18
},
"mapUrl": "/api/v2/map?lat=35.360556&lon=138.727778&zoom=15&tile=gsi&label=%E5%AF%8C%E5%A3%AB%E5%B1%B1",
"embedUrl": "/api/v2/map?lat=35.360556&lon=138.727778&zoom=15&tile=gsi&label=%E5%AF%8C%E5%A3%AB%E5%B1%B1&embed=true",
"externalLinks": {
"googleMaps": "https://www.google.com/maps?q=35.360556,138.727778",
"openStreetMap": "https://www.openstreetmap.org/?mlat=35.360556&mlon=138.727778#map=15/35.360556/138.727778",
"gsiMaps": "https://maps.gsi.go.jp/#15/35.360556/138.727778/"
},
"nearby": [
{
"kind": "sota",
"code": "JA/YN-001",
"name": "Mt.Fuji",
"nameJ": "富士山",
"latitude": 35.360556,
"longitude": 138.727778,
"distanceM": 0,
"altM": 3776,
"points": 10,
"location": "静岡県富士宮市"
}
]
}
管理コンソール(admin/)のSOTA/POTAリファレンス編集画面には、
編集中の座標を地図で開く「🗺 地図で位置を確認」ボタンを追加しています。
| 変数名 | 説明 | デフォルト |
|---|---|---|
DATABASE_URL | データベースURL | sqlite:sotaapp2.db |
CF_ACCESS_TEAM_DOMAIN / CF_ACCESS_AUD | Cloudflare Access のチームのドメインとアプリの識別子(両方そろうと管理画面の署名を検証) | - |
HOST | バインドホスト | 0.0.0.0 |
PORT | ポート番号 | 8080 |
LOG_LEVEL | ログレベル | info |
詳細はdocker-compose.yaml参照。
# 全テスト実行
makers test
# CI用テスト(fmt-check + clippy-strict + test)
makers ci
Dockerイメージに対する包括的なE2Eテストを実行します。
# Dockerイメージをビルドしてテスト実行
makers e2e
# 既存イメージでテストのみ実行
makers e2e-test jl1nie/sotaapp2:latest
# テストサーバー起動(手動確認用)
makers e2e-server
makers e2e-stop
E2Eテストは以下の4フェーズで構成されています:
| フェーズ | テスト内容 |
|---|---|
| BUILD | 実行ファイル・migrations・staticの存在確認 |
| RUNTIME | SSL/TLS接続・ca-certificates・libssl確認 |
| APP | CLIコマンド(help, migrate等)の動作確認 |
| SERVER/API | サーバー起動・ヘルスチェック・主要APIエンドポイント |
詳細は docs/docker-e2e-test-plan.md を参照。
GitHub Actionsで以下が自動実行されます:
詳細は docs/deployment-manual.md を参照。
# 通常デプロイ(バックアップ付き)
makers deploy
# バックアップなしデプロイ
makers deploy-no-backup
# Fly.io直接デプロイ
makers fly-deploy
# バックアップ作成
makers fly-backup
# バックアップ一覧
makers fly-db-list
# リストア
makers fly-db-restore /data/backup_YYYYMMDD_HHMMSS.db
# 最適化
makers fly-db-optimize
詳しい開発フローは Repository Guidelines を参照してください。
本プロジェクトは Apache License 2.0 の下で公開されています。
Copyright 2024-2026 Minoru Tomobe (JL1NIE)
Happy Coding! 73! 🎯📡