AdCloud Server
面向开发者和 coding agent 的广告云埋点与广告推送后端。使用 FastAPI 开发,Python 依赖和虚拟环境统一由 uv 管理。
已实现 /v1 Gateway 路由、匿名身份签发、ID 映射图谱、可信身份 Stitch、稀疏画像及历史事件回溯。
画像可按部署设置选择关系库读取或 Cassandra 宽表投影;身份图谱保持关系库事务一致性。
广告业务目前仅有路由探测,尚未实现投放引擎。邮箱/手机号 OTP 和具体 OAuth 登录需要由调用方接入验证。
本地开发(无需安装数据库服务)
uv sync --locked
uv run python scripts/init_local_env.py
uv run uvicorn adcloud_server.main:app --reload --host 127.0.0.1 --port 8000
初始化脚本生成被 Git 忽略的 .env,权限 0600,包含本地开发所需随机 secret,不输出 secret 值,不覆盖已有文件。
SQLite 数据存放于 .data/,同样不提交。身份服务缺少 IDENTITY_SECRET 时返回 503,系统健康接口仍可用。
环境变量优先于 .env。生产 HTTPS 部署将 COOKIE_SECURE 设置为 true。
- 系统健康检查:
http://localhost:8000/health - API 文档:
http://localhost:8000/docs - OpenAPI:
http://localhost:8000/openapi.json
另一个终端可运行 uv run python scripts/demo_identity.py,演示匿名访问、埋点、临时画像、模拟验证后 Stitch 及继承结果。
演示脚本使用合成的已验证身份,不代替实际 OTP/OAuth 校验。
HTTP Gateway
HTTPS :443 (Nginx,终止 TLS)
├── /v1/events/* → 事件接收、历史查询
├── /v1/users/* → 稀疏用户画像
├── /v1/ads/* → 广告业务模块(待实现)
├── /v1/identity/* → 匿名 ID、解析、拼接与图谱
└── /v1/... → 后续业务模块
↓
FastAPI 127.0.0.1:8000
各模块当前共用一个进程,独立注册在 api/v1/router.py 中;Nginx 为各域预留独立 upstream。
未知路由返回 404、不支持的方法返回 405。保留各模块 /health 探测以及旧系统 /health。
默认 CORS 允许 localhost:3000、5173、5174,启用 credentials;匿名写请求检查浏览器 Origin。
deploy/nginx.conf.example 放在 Nginx http {} 上下文,替换域名和证书路径后在部署环境执行 nginx -t。
精确匹配 /v1/events 防止 POST 被重定向为带尾斜杠路径,所有转发保留 /v1、业务前缀和查询参数。
配置未在本机部署或验证,未启动 443、未申请证书。API 文档仅通过内部地址访问。
Identity Resolution / Stitching
详见 身份图谱与存储配置,包含接口、合并策略、共享设备处理和 PostgreSQL / Cassandra 部署选择。
- Cookie / token 只证明匿名设备持有,不能自行提交
verified=true合并账户。 - Stitch、图谱、画像读写和历史查询仅允许携带 SERVICE_TOKEN 的可信后端。
- 匿名事件保留原始 ID,通过 alias 在合并后即时归入 Master ID。
- PostgreSQL JSONB / SQLite JSON 省略空属性;Cassandra 可选宽表投影通过事务 outbox 同步和故障重试。
- 图谱主库始终是关系库,不提供纯 Cassandra、HBase 或 Bigtable 图谱实现。
检查
uv run pytest
uv run ruff check .
uv run ruff format --check .
默认测试使用临时 SQLite 和可恢复的投影替身,不安装、不启动数据库服务。 PostgreSQL、Cassandra 联调入口默认跳过,等提供专用测试环境后使用:
uv sync --locked --extra postgres --extra cassandra
- 设置
ADCLOUD_TEST_POSTGRES_URL为专用测试 PostgreSQL 的 SQLAlchemy URL,然后运行uv run --extra postgres pytest tests/test_postgres.py。 - 设置
ADCLOUD_TEST_CASSANDRA_HOSTS、ADCLOUD_TEST_CASSANDRA_KEYSPACE和可选的 PORT、USERNAME、PASSWORD、TLS、CA_FILE,同前缀环境变量配置;先在专用集群应用deploy/cassandra.cql,再运行uv run --extra cassandra pytest tests/test_cassandra.py。
联调测试使用独立随机租户,不自动创建 Cassandra 集群。PostgreSQL 测试会创建初始表并保留测试租户数据,需使用专用测试数据库。
Docker / CI/CD
Dockerfile 提供 test、runtime 两个目标;Gitea Actions 在 main 推送后构建、测试并部署到 runner 的 Docker daemon,默认映射宿主机 18080 到容器 8000。 详细配置、runner 要求、公网端口、持久化和回滚见 Docker 部署说明。
测试部署使用 compose.yml 编排 PostgreSQL、Cassandra、API 与画像 worker;CI 运行全部数据库集成测试,公网 API 默认 http://47.76.92.159:18080/docs。详见 Docker 部署文档。
事件字典与标准特征
已录入 33 个标准事件,涵盖访问与内容、电商交易、注册留资、广告和推送,支持客户事件别名、参数版本、草稿试算、不可变规则发布、停用和回滚。
默认接收端必须携带应用接入凭据及已发布事件版本;未注册或参数不符的事件不入库。
新增 adcloud-events worker 将事件按冻结的规则版本转成可去重的标准特征贡献;画像提供时间窗口和上限,身份缝合后自动汇总。
本地可运行 uv run adcloud-events,Cassandra 模式还需 uv run adcloud-profiles。
完整目录、API、配置和兼容说明见 事件注册表。
开发者控制台已加入事件字典页面;客户账号登录和角色授权尚未接入,目前使用应用范围管理凭据。
广告主控制台
新增独立 /v1/advertiser 注册登录、主子账户和项目 API。广告主身份与终端流量用户 identity 分离;详细接口、部署要求和首版边界见 广告主 API。广告主认证不依赖 IDENTITY_SECRET,应用启动会初始化共享数据库。