2
1
Fork
You've already forked analytics
0
Služba na sbírání analytik zaměřená na jednoduchost a soukromí
  • Rust 90.1%
  • Nix 9.9%
2026年02月10日 20:52:56 +01:00
migrations Pridani indexu na project_id 2026年02月10日 20:52:56 +01:00
src Initialize repository 2026年02月10日 20:42:15 +01:00
.gitignore Initialize repository 2026年02月10日 20:42:15 +01:00
Cargo.lock Initialize repository 2026年02月10日 20:42:15 +01:00
Cargo.toml Initialize repository 2026年02月10日 20:42:15 +01:00
flake.lock Initialize repository 2026年02月10日 20:42:15 +01:00
flake.nix Initialize repository 2026年02月10日 20:42:15 +01:00
README.md Initialize repository 2026年02月10日 20:42:15 +01:00

osmapcz analytická služba

Vlastnosti:

  • IP se ukládá zahashovaná
  • podpora více projektů
  • možnost vytvářet veřejné výstupy

Instance: https://analytics.xn--eicha-hcbb.fun/

V hostované instanci se momentálně vyskytují tyto projekty:

  • fody-app (pouze pro testování dovedností API, v aplikaci se nevyužívá)

API

Nahrání záznamu

POST /api/1/<project id>/log

type Body = {
 data: { [key: string]: string | number | null };
};

Stažení výstupu

GET /api/1/<project id>/output/<output id>

Konfigurace projektu

  • DATABASE_URL - PostgreSQL connection string
  • RUST_LOG - env_logger konfigurace
  • CONFIG_PATH - cesta ke konfiguračnímu .toml souboru

Příklad konfiguračního souboru

[project.fody-app]
[project.fody-app.output.public]
fields = {
 platformsLastWeek = {
 type = "query-all",
 columns = {
 platform = "string",
 count = "int"
 },
 query = """
 SELECT
 (data ->> 'platform')::TEXT AS platform,
 COUNT(*) AS count
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'platform') = 'string' AND
 received > now() - interval '7 day'
 GROUP BY
 data ->> 'platform'
 """,
 },
 screenSizesLastWeek = {
 type = "query-all",
 columns = {
 screenWidth = "float",
 screenHeight = "float",
 count = "int"
 },
 query = """
 SELECT
 (data ->> 'screenWidth')::DOUBLE PRECISION AS screenWidth,
 (data ->> 'screenHeight')::DOUBLE PRECISION AS screenHeight,
 COUNT(*) AS count
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'screenWidth') = 'number' AND
 jsonb_typeof(data -> 'screenHeight') = 'number' AND
 received > now() - interval '7 day'
 GROUP BY
 data ->> 'screenWidth',
 data ->> 'screenHeight'
 """,
 },
 versionsLastWeek = {
 type = "query-all",
 columns = {
 version = "string",
 count = "int"
 },
 query = """
 SELECT
 (data ->> 'version')::TEXT AS version,
 COUNT(*) AS count
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'version') = 'string' AND
 received > now() - interval '7 day'
 GROUP BY
 data ->> 'version'
 """,
 },
 activeTabsLastWeek = {
 type = "query-all",
 columns = {
 tab = "string",
 duration = "float"
 },
 query = """
 SELECT
 (data ->> 'activeTab')::TEXT AS tab,
 (data ->> 'sessionDurationMs')::DOUBLE PRECISION AS duration
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'activeTab') = 'string' AND
 jsonb_typeof(data -> 'sessionDurationMs') = 'number' AND
 received > now() - interval '7 day'
 """,
 },
 activeTabAvarageLastWeek = {
 type = "query-all",
 columns = {
 tab = "string",
 duration = "float"
 },
 query = """
 SELECT
 (data ->> 'activeTab')::TEXT AS tab,
 AVG((data ->> 'sessionDurationMs')::DOUBLE PRECISION) AS duration
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'activeTab') = 'string' AND
 jsonb_typeof(data -> 'sessionDurationMs') = 'number' AND
 received > now() - interval '7 day'
 GROUP BY
 data ->> 'activeTab'
 """,
 },
 uniqueDevicesLastWeek = {
 type = "query-single",
 columns = {
 count = "int",
 },
 query = """
 SELECT COUNT(*) AS count FROM (
 SELECT
 FROM datapoints
 WHERE
 project_id = 1ドル AND
 jsonb_typeof(data -> 'deviceId') = 'string' AND
 received > now() - interval '7 day'
 GROUP BY
 data ->> 'deviceId'
 )
 """,
 },
}