fully migrate "interim" nomenclature to "phonograph"

This commit is contained in:
Brent Schroeter 2025-11-19 01:45:58 +00:00
parent 624bfa2d93
commit 843750ac76
118 changed files with 189 additions and 263 deletions

176
Cargo.lock generated
View file

@ -1750,94 +1750,6 @@ dependencies = [
"hashbrown 0.15.5", "hashbrown 0.15.5",
] ]
[[package]]
name = "interim-models"
version = "0.0.1"
dependencies = [
"bigdecimal",
"chrono",
"derive_builder",
"futures",
"interim-pgtypes",
"redact",
"regex",
"serde",
"serde_json",
"sqlx",
"strum",
"thiserror 2.0.12",
"tracing",
"url",
"uuid",
"validator",
]
[[package]]
name = "interim-namegen"
version = "0.0.1"
dependencies = [
"rand 0.8.5",
"thiserror 2.0.12",
]
[[package]]
name = "interim-pgtypes"
version = "0.0.1"
dependencies = [
"chrono",
"derive_builder",
"nom 8.0.0",
"regex",
"serde",
"sqlx",
"strum",
"thiserror 2.0.12",
"uuid",
]
[[package]]
name = "interim-server"
version = "0.0.1"
dependencies = [
"anyhow",
"askama",
"async-session",
"axum",
"axum-extra",
"bigdecimal",
"chrono",
"clap",
"config",
"derive_builder",
"dotenvy",
"futures",
"headers",
"interim-models",
"interim-namegen",
"interim-pgtypes",
"markdown",
"oauth2",
"percent-encoding",
"rand 0.8.5",
"redact",
"regex",
"reqwest 0.12.15",
"scraper",
"serde",
"serde_json",
"sqlx",
"strum",
"thiserror 2.0.12",
"tokio",
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
"url",
"uuid",
"validator",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.11.0" version = "2.11.0"
@ -2409,6 +2321,94 @@ dependencies = [
"siphasher", "siphasher",
] ]
[[package]]
name = "phono-backends"
version = "0.0.1"
dependencies = [
"chrono",
"derive_builder",
"nom 8.0.0",
"regex",
"serde",
"sqlx",
"strum",
"thiserror 2.0.12",
"uuid",
]
[[package]]
name = "phono-models"
version = "0.0.1"
dependencies = [
"bigdecimal",
"chrono",
"derive_builder",
"futures",
"phono-backends",
"redact",
"regex",
"serde",
"serde_json",
"sqlx",
"strum",
"thiserror 2.0.12",
"tracing",
"url",
"uuid",
"validator",
]
[[package]]
name = "phono-namegen"
version = "0.0.1"
dependencies = [
"rand 0.8.5",
"thiserror 2.0.12",
]
[[package]]
name = "phono-server"
version = "0.0.1"
dependencies = [
"anyhow",
"askama",
"async-session",
"axum",
"axum-extra",
"bigdecimal",
"chrono",
"clap",
"config",
"derive_builder",
"dotenvy",
"futures",
"headers",
"markdown",
"oauth2",
"percent-encoding",
"phono-backends",
"phono-models",
"phono-namegen",
"rand 0.8.5",
"redact",
"regex",
"reqwest 0.12.15",
"scraper",
"serde",
"serde_json",
"sqlx",
"strum",
"thiserror 2.0.12",
"tokio",
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
"url",
"uuid",
"validator",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.16" version = "0.2.16"

View file

@ -2,7 +2,7 @@ cargo-features = ["codegen-backend"]
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["interim-*"] members = ["phono-*"]
[workspace.package] [workspace.package]
version = "0.0.1" version = "0.0.1"
@ -14,9 +14,9 @@ bigdecimal = { version = "0.4.9", features = ["serde-json"] }
chrono = { version = "0.4.41", features = ["serde"] } chrono = { version = "0.4.41", features = ["serde"] }
derive_builder = "0.20.2" derive_builder = "0.20.2"
futures = "0.3.31" futures = "0.3.31"
interim-models = { path = "./interim-models" } phono-backends = { path = "./phono-backends" }
interim-namegen = { path = "./interim-namegen" } phono-models = { path = "./phono-models" }
interim-pgtypes = { path = "./interim-pgtypes" } phono-namegen = { path = "./phono-namegen" }
rand = "0.8.5" rand = "0.8.5"
redact = { version = "0.1.11", features = ["serde", "zeroize"] } redact = { version = "0.1.11", features = ["serde", "zeroize"] }
regex = "1.11.1" regex = "1.11.1"

View file

@ -11,16 +11,16 @@ COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json RUN cargo chef cook --release --recipe-path recipe.json
# Build application # Build application
COPY . . COPY . .
RUN cargo build --release --bin interim RUN cargo build --release --bin phonograph
# We do not need the Rust toolchain to run the binary! # We do not need the Rust toolchain to run the binary!
FROM debian:bookworm-slim AS runtime FROM debian:bookworm-slim AS runtime
RUN apt-get update && apt-get install -y libpq-dev RUN apt-get update && apt-get install -y libpq-dev
WORKDIR /app WORKDIR /app
COPY --from=builder /app/target/release/interim /usr/local/bin COPY --from=builder /app/target/release/phonograph /usr/local/bin
COPY ./css_dist ./css_dist COPY ./css_dist ./css_dist
COPY ./js_dist ./js_dist COPY ./js_dist ./js_dist
COPY ./static ./static COPY ./static ./static
ENTRYPOINT ["/usr/local/bin/interim"] ENTRYPOINT ["/usr/local/bin/phonograph"]

View file

@ -12,22 +12,3 @@ services:
volumes: volumes:
- "./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro" - "./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro"
- "./pgdata:/var/lib/postgresql/18/docker" - "./pgdata:/var/lib/postgresql/18/docker"
# keycloak:
# depends_on: [pg]
# restart: always
# build:
# context: .
# dockerfile: keycloak.dockerfile
# environment:
# KC_DB: postgres
# KC_DB_URL: jdbc:postgresql://pg:5432/keycloak
# KC_DB_USERNAME: keycloak
# KC_DB_PASSWORD: guest
# KC_HOSTNAME: 0.0.0.0
# KEYCLOAK_ADMIN: admin
# KEYCLOAK_ADMIN_PASSWORD: guest
# command: [start, --optimized]
# ports:
# - "127.0.0.1:9000:9000"
# - "127.0.0.1:8443:8443"

View file

@ -1,3 +0,0 @@
CREATE USER interim_app WITH ENCRYPTED PASSWORD 'guest';
CREATE DATABASE interim_app;
ALTER DATABASE interim_app OWNER TO interim_app;

View file

@ -1,3 +0,0 @@
CREATE USER keycloak WITH ENCRYPTED PASSWORD 'guest';
CREATE DATABASE keycloak;
ALTER DATABASE keycloak OWNER TO keycloak;

View file

@ -1,18 +0,0 @@
FROM quay.io/keycloak/keycloak:26.3.2 as builder
# Enable health and metrics support
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
# Configure a database vendor
ENV KC_DB=postgres
WORKDIR /opt/keycloak
# for demonstration purposes only, please make sure to use proper certificates in production instead
RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:26.3.2
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

View file

@ -1,20 +0,0 @@
use askama::Template;
use interim_pgtypes::pg_role::{PgRole, RoleTree};
#[derive(Clone, Debug, Template)]
#[template(path = "role_tree.html")]
pub struct RenderableRoleTree {
role: PgRole,
branches: Vec<RenderableRoleTree>,
inherit: bool,
}
impl From<RoleTree> for RenderableRoleTree {
fn from(value: RoleTree) -> Self {
Self {
role: value.role,
branches: value.branches.into_iter().map(Self::from).collect(),
inherit: value.inherit,
}
}
}

View file

@ -1,12 +0,0 @@
<div class="role-tree {%- if !inherit %} role-tree--no-inherit{% endif -%}">
<div class="role-tree__rolname">
{{ role.rolname }}
</div>
{% if !branches.is_empty() %}
<ul class="role-tree__branches">
{% for branch in branches %}
<li class="role-tree__branch">{{ branch.render()? | safe }}</li>
{% endfor %}
</ul>
{% endif %}
</div>

View file

@ -1,5 +1,5 @@
[package] [package]
name = "interim-pgtypes" name = "phono-backends"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true

View file

@ -3,7 +3,7 @@ use sqlx::{postgres::types::Oid, prelude::FromRow, query_as};
use thiserror::Error; use thiserror::Error;
use uuid::Uuid; use uuid::Uuid;
use crate::client::WorkspaceClient; use crate::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER};
#[derive(Clone, Debug, Eq, Hash, FromRow, PartialEq)] #[derive(Clone, Debug, Eq, Hash, FromRow, PartialEq)]
pub struct PgRole { pub struct PgRole {
@ -356,18 +356,18 @@ fn compute_members(rows: &Vec<RoleTreeRow>, root: Oid) -> Vec<RoleTree> {
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum RolnameParseError { pub enum RolnameParseError {
#[error("rolname does not have interim user prefix")] #[error("rolname does not have phono user prefix")]
MissingPrefix, MissingPrefix,
#[error("unable to parse uuid from rolname: {0}")] #[error("unable to parse uuid from rolname: {0}")]
BadUuid(uuid::Error), BadUuid(uuid::Error),
} }
pub fn user_id_from_rolname(rolname: &str, role_prefix: &str) -> Result<Uuid, RolnameParseError> { pub fn user_id_from_rolname(rolname: &str) -> Result<Uuid, RolnameParseError> {
if !rolname.starts_with(role_prefix) { if rolname.starts_with(ROLE_PREFIX_USER) {
Err(RolnameParseError::MissingPrefix)
} else {
let mut rolname = rolname.to_owned(); let mut rolname = rolname.to_owned();
rolname.replace_range(0..role_prefix.len(), ""); rolname.replace_range(0..ROLE_PREFIX_USER.len(), "");
Uuid::parse_str(&rolname).map_err(RolnameParseError::BadUuid) Uuid::parse_str(&rolname).map_err(RolnameParseError::BadUuid)
} else {
Err(RolnameParseError::MissingPrefix)
} }
} }

View file

@ -1,5 +1,5 @@
[package] [package]
name = "interim-models" name = "phono-models"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true
@ -8,7 +8,7 @@ bigdecimal = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
derive_builder = { workspace = true } derive_builder = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
interim-pgtypes = { path = "../interim-pgtypes" } phono-backends = { workspace = true }
redact = { workspace = true } redact = { workspace = true }
regex = { workspace = true } regex = { workspace = true }
serde = { workspace = true } serde = { workspace = true }

View file

@ -1,7 +1,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use derive_builder::Builder; use derive_builder::Builder;
use interim_pgtypes::{ use phono_backends::{
client::WorkspaceClient, pg_acl::PgPrivilegeType, pg_class::PgClass, pg_role::RoleTree, client::WorkspaceClient, pg_acl::PgPrivilegeType, pg_class::PgClass, pg_role::RoleTree,
rolnames::ROLE_PREFIX_USER, rolnames::ROLE_PREFIX_USER,
}; };

View file

@ -1,6 +1,6 @@
use std::fmt::Display; use std::fmt::Display;
use interim_pgtypes::escape_identifier; use phono_backends::escape_identifier;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::datum::Datum; use crate::datum::Datum;

View file

@ -1,7 +1,7 @@
use bigdecimal::BigDecimal; use bigdecimal::BigDecimal;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use derive_builder::Builder; use derive_builder::Builder;
use interim_pgtypes::pg_attribute::PgAttribute; use phono_backends::pg_attribute::PgAttribute;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::Acquire as _; use sqlx::Acquire as _;
use sqlx::{ use sqlx::{

View file

@ -1,4 +1,4 @@
use interim_pgtypes::pg_attribute::PgAttribute; use phono_backends::pg_attribute::PgAttribute;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum::{EnumDiscriminants, EnumIter, EnumString}; use strum::{EnumDiscriminants, EnumIter, EnumString};

View file

@ -1,6 +1,6 @@
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use derive_builder::Builder; use derive_builder::Builder;
use interim_pgtypes::pg_acl::PgPrivilegeType; use phono_backends::pg_acl::PgPrivilegeType;
use sqlx::{postgres::types::Oid, query_as}; use sqlx::{postgres::types::Oid, query_as};
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,5 +1,5 @@
[package] [package]
name = "interim-namegen" name = "phono-namegen"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true

View file

@ -6,12 +6,12 @@
//! ### Basic Usage //! ### Basic Usage
//! //!
//! ``` //! ```
//! let name: String = interim_namegen::default_generator().generate_name(3); //! let name: String = phono_namegen::default_generator().generate_name(3);
//! ``` //! ```
use std::sync::LazyLock; use std::sync::LazyLock;
use rand::{Rng, rngs::ThreadRng, seq::SliceRandom}; use rand::{rngs::ThreadRng, seq::SliceRandom, Rng};
// EFF wordlist for random password phrases. // EFF wordlist for random password phrases.
// //
@ -36,11 +36,13 @@ const WORDLIST_LEN: usize = 7776;
// LazyLock. // LazyLock.
static WORDLIST: LazyLock<[&str; WORDLIST_LEN]> = LazyLock::new(|| { static WORDLIST: LazyLock<[&str; WORDLIST_LEN]> = LazyLock::new(|| {
let mut words = [""; WORDLIST_LEN]; let mut words = [""; WORDLIST_LEN];
// Embed wordlist file rather than attempt to fetch it from disk at runtime.
for (i, word) in include_str!("./eff_large_wordlist.txt") for (i, word) in include_str!("./eff_large_wordlist.txt")
.split('\n') .split('\n')
.enumerate() .enumerate()
{ {
assert!(i <= WORDLIST_LEN); // The wordlist may contain a trailing newline. // The wordlist may contain a trailing newline.
assert!(i <= WORDLIST_LEN);
if i < WORDLIST_LEN { if i < WORDLIST_LEN {
words[i] = word; words[i] = word;
} }

View file

@ -1,5 +1,5 @@
[package] [package]
name = "interim-server" name = "phono-server"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true
@ -17,12 +17,12 @@ derive_builder = { workspace = true }
dotenvy = "0.15.7" dotenvy = "0.15.7"
futures = { workspace = true } futures = { workspace = true }
headers = "0.4.1" headers = "0.4.1"
interim-models = { workspace = true }
interim-namegen = { workspace = true }
interim-pgtypes = { workspace = true }
markdown = "1.0.0" markdown = "1.0.0"
oauth2 = "4.4.2" oauth2 = "4.4.2"
percent-encoding = "2.3.1" percent-encoding = "2.3.1"
phono-backends = { workspace = true }
phono-models = { workspace = true }
phono-namegen = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
redact = { workspace = true } redact = { workspace = true }
regex = { workspace = true } regex = { workspace = true }

View file

@ -3,8 +3,8 @@ use axum::{
extract::{FromRef, FromRequestParts}, extract::{FromRef, FromRequestParts},
http::request::Parts, http::request::Parts,
}; };
use interim_models::client::AppDbClient;
use oauth2::basic::BasicClient; use oauth2::basic::BasicClient;
use phono_models::client::AppDbClient;
use sqlx::postgres::PgPoolOptions; use sqlx::postgres::PgPoolOptions;
use crate::{ use crate::{

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use interim_models::{field::Field, language::Language}; use phono_models::{field::Field, language::Language};
use serde::Serialize; use serde::Serialize;
#[derive(Clone, Debug, Serialize)] #[derive(Clone, Debug, Serialize)]

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use clap::Parser as _; use clap::Parser as _;
use dotenvy::dotenv; use dotenvy::dotenv;
use interim_models::MIGRATOR; use phono_models::MIGRATOR;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use crate::{ use crate::{
@ -19,7 +19,6 @@ mod field_info;
mod middleware; mod middleware;
mod navigator; mod navigator;
mod presentation_form; mod presentation_form;
mod renderable_role_tree;
mod roles; mod roles;
mod routes; mod routes;
mod sessions; mod sessions;

View file

@ -1,6 +1,6 @@
use std::iter::zip; use std::iter::zip;
use interim_models::presentation::{ use phono_models::presentation::{
DropdownOption, Presentation, PresentationDiscriminants, RFC_3339_S, TextInputMode, DropdownOption, Presentation, PresentationDiscriminants, RFC_3339_S, TextInputMode,
}; };
use serde::Deserialize; use serde::Deserialize;

View file

@ -2,7 +2,7 @@ use std::collections::HashSet;
use anyhow::anyhow; use anyhow::anyhow;
use askama::Template; use askama::Template;
use interim_pgtypes::{ use phono_backends::{
client::WorkspaceClient, client::WorkspaceClient,
pg_acl::{PgAclItem, PgPrivilegeType}, pg_acl::{PgAclItem, PgPrivilegeType},
pg_class::PgClass, pg_class::PgClass,
@ -105,7 +105,7 @@ impl RoleDisplay {
oid: Oid, oid: Oid,
relname: String, relname: String,
} }
// TODO: Consider moving this to [`interim-pgtypes`]. // TODO: Consider moving this to [`phono_backends`].
let mut rels: Vec<RelInfo> = query_as( let mut rels: Vec<RelInfo> = query_as(
r#" r#"
select oid, any_value(relname) as relname select oid, any_value(relname) as relname

View file

@ -5,14 +5,14 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse as _, Response}, response::{Html, IntoResponse as _, Response},
}; };
use interim_models::{ use phono_backends::pg_attribute::PgAttribute;
use phono_models::{
field::Field, field::Field,
field_form_prompt::FieldFormPrompt, field_form_prompt::FieldFormPrompt,
language::Language, language::Language,
portal::Portal, portal::Portal,
presentation::{Presentation, TextInputMode}, presentation::{Presentation, TextInputMode},
}; };
use interim_pgtypes::pg_attribute::PgAttribute;
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid; use uuid::Uuid;

View file

@ -6,12 +6,12 @@ use axum::{
// [`axum_extra`]'s form extractor is preferred: // [`axum_extra`]'s form extractor is preferred:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::{ use phono_backends::{escape_identifier, pg_class::PgClass};
use phono_models::{
accessors::{Accessor as _, Actor, portal::PortalAccessor}, accessors::{Accessor as _, Actor, portal::PortalAccessor},
field::Field, field::Field,
presentation::Presentation, presentation::Presentation,
}; };
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
use serde::Deserialize; use serde::Deserialize;
use sqlx::{postgres::types::Oid, query}; use sqlx::{postgres::types::Oid, query};
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,5 +1,5 @@
use axum::{extract::Path, response::IntoResponse}; use axum::{extract::Path, response::IntoResponse};
use interim_models::portal::Portal; use phono_models::portal::Portal;
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -6,7 +6,8 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::{ use phono_backends::pg_attribute::PgAttribute;
use phono_models::{
accessors::{Accessor as _, Actor, portal::PortalAccessor}, accessors::{Accessor as _, Actor, portal::PortalAccessor},
field::Field, field::Field,
field_form_prompt::FieldFormPrompt, field_form_prompt::FieldFormPrompt,
@ -15,7 +16,6 @@ use interim_models::{
portal::Portal, portal::Portal,
workspace::Workspace, workspace::Workspace,
}; };
use interim_pgtypes::pg_attribute::PgAttribute;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use strum::IntoEnumIterator as _; use strum::IntoEnumIterator as _;

View file

@ -5,14 +5,14 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{IntoResponse as _, Response}, response::{IntoResponse as _, Response},
}; };
use interim_models::{ use phono_backends::{
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
};
use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
datum::Datum, datum::Datum,
field::Field, field::Field,
}; };
use interim_pgtypes::{
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{ use sqlx::{
postgres::{PgRow, types::Oid}, postgres::{PgRow, types::Oid},

View file

@ -8,11 +8,11 @@ use axum::{
// [`axum_extra`]'s form extractor is required to support repeated keys: // [`axum_extra`]'s form extractor is required to support repeated keys:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::{ use phono_backends::{escape_identifier, pg_acl::PgPrivilegeType, pg_class::PgClass};
use phono_models::{
accessors::{Accessor as _, Actor, portal::PortalAccessor}, accessors::{Accessor as _, Actor, portal::PortalAccessor},
datum::Datum, datum::Datum,
}; };
use interim_pgtypes::{escape_identifier, pg_acl::PgPrivilegeType, pg_class::PgClass};
use serde::Deserialize; use serde::Deserialize;
use sqlx::{postgres::types::Oid, query}; use sqlx::{postgres::types::Oid, query};
use uuid::Uuid; use uuid::Uuid;

View file

@ -3,12 +3,12 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse as _, Response}, response::{Html, IntoResponse as _, Response},
}; };
use interim_models::{ use phono_backends::{pg_acl::PgPrivilegeType, pg_attribute::PgAttribute};
use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
expression::PgExpressionAny, expression::PgExpressionAny,
workspace::Workspace, workspace::Workspace,
}; };
use interim_pgtypes::{pg_acl::PgPrivilegeType, pg_attribute::PgAttribute};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -4,7 +4,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::{ use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
portal::Portal, portal::Portal,
workspace::Workspace, workspace::Workspace,

View file

@ -3,11 +3,11 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::Response, response::Response,
}; };
use interim_models::{ use phono_backends::{escape_identifier, pg_class::PgClass};
use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
field::Field, field::Field,
}; };
use interim_pgtypes::{escape_identifier, pg_class::PgClass};
use serde::Deserialize; use serde::Deserialize;
use sqlx::{postgres::types::Oid, query}; use sqlx::{postgres::types::Oid, query};
use uuid::Uuid; use uuid::Uuid;

View file

@ -6,7 +6,7 @@ use axum::{
// [`axum_extra`]'s form extractor is preferred: // [`axum_extra`]'s form extractor is preferred:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::{ use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
expression::PgExpressionAny, expression::PgExpressionAny,
portal::Portal, portal::Portal,

View file

@ -4,8 +4,8 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::workspace::Workspace; use phono_backends::pg_class::PgClass;
use interim_pgtypes::pg_class::PgClass; use phono_models::workspace::Workspace;
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -2,8 +2,8 @@ use axum::{debug_handler, extract::Path, response::Response};
// [`axum_extra`]'s form extractor is preferred: // [`axum_extra`]'s form extractor is preferred:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::rel_invitation::RelInvitation; use phono_backends::pg_acl::PgPrivilegeType;
use interim_pgtypes::pg_acl::PgPrivilegeType; use phono_models::rel_invitation::RelInvitation;
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,5 +1,5 @@
use axum::{debug_handler, extract::Path, response::Response}; use axum::{debug_handler, extract::Path, response::Response};
use interim_models::{field::Field, presentation::Presentation}; use phono_models::{field::Field, presentation::Presentation};
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,5 +1,5 @@
use axum::{debug_handler, extract::Path, response::Response}; use axum::{debug_handler, extract::Path, response::Response};
use interim_models::field::Field; use phono_models::field::Field;
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -4,7 +4,7 @@ use axum::{debug_handler, extract::Path, response::Response};
// [`axum_extra`]'s form extractor is required to support repeated keys: // [`axum_extra`]'s form extractor is required to support repeated keys:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::form_transition::{self, FormTransition}; use phono_models::form_transition::{self, FormTransition};
use serde::Deserialize; use serde::Deserialize;
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -3,7 +3,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::Response, response::Response,
}; };
use interim_models::{ use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
portal::{Portal, RE_PORTAL_NAME}, portal::{Portal, RE_PORTAL_NAME},
}; };

View file

@ -8,7 +8,7 @@ use axum::{
// [`axum_extra`]'s form extractor is required to support repeated keys: // [`axum_extra`]'s form extractor is required to support repeated keys:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform // https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form; use axum_extra::extract::Form;
use interim_models::{ use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
field::Field, field::Field,
field_form_prompt::FieldFormPrompt, field_form_prompt::FieldFormPrompt,

View file

@ -5,7 +5,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::Response, response::Response,
}; };
use interim_pgtypes::{escape_identifier, pg_class::PgClass}; use phono_backends::{escape_identifier, pg_class::PgClass};
use regex::Regex; use regex::Regex;
use serde::Deserialize; use serde::Deserialize;
use sqlx::{postgres::types::Oid, query}; use sqlx::{postgres::types::Oid, query};
@ -64,7 +64,7 @@ pub(super) async fn post(
.await?; .await?;
// FIXME ensure that user has ownership of the table. // FIXME ensure that user has ownership of the table.
// TODO: move this to a function in `interim-pgtypes`. // TODO: move this to a function in `phono_backends`.
query(&format!( query(&format!(
"alter table {ident} rename to {name_esc}", "alter table {ident} rename to {name_esc}",
ident = rel.get_identifier(), ident = rel.get_identifier(),

View file

@ -5,13 +5,13 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{IntoResponse as _, Response}, response::{IntoResponse as _, Response},
}; };
use interim_models::{ use phono_backends::{
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
};
use phono_models::{
accessors::{Accessor, Actor, portal::PortalAccessor}, accessors::{Accessor, Actor, portal::PortalAccessor},
datum::Datum, datum::Datum,
}; };
use interim_pgtypes::{
escape_identifier, pg_acl::PgPrivilegeType, pg_attribute::PgAttribute, pg_class::PgClass,
};
use serde::Deserialize; use serde::Deserialize;
use serde_json::json; use serde_json::json;
use sqlx::{Acquire as _, postgres::types::Oid, query}; use sqlx::{Acquire as _, postgres::types::Oid, query};

View file

@ -1,9 +1,9 @@
use axum::{extract::State, response::IntoResponse}; use axum::{extract::State, response::IntoResponse};
use interim_models::{ use phono_backends::{client::WorkspaceClient, escape_identifier, rolnames::ROLE_PREFIX_USER};
use phono_models::{
client::AppDbClient, cluster::Cluster, user::User, workspace::Workspace, client::AppDbClient, cluster::Cluster, user::User, workspace::Workspace,
workspace_user_perm::WorkspaceMembership, workspace_user_perm::WorkspaceMembership,
}; };
use interim_pgtypes::{client::WorkspaceClient, escape_identifier, rolnames::ROLE_PREFIX_USER};
use sqlx::{Connection as _, PgConnection, query}; use sqlx::{Connection as _, PgConnection, query};
use crate::{ use crate::{
@ -33,7 +33,7 @@ pub(super) async fn post(
// WARNING: `db_name` is injected directly into the `create database` SQL // WARNING: `db_name` is injected directly into the `create database` SQL
// command. It **must not** contain spaces or any other unsafe characters. // command. It **must not** contain spaces or any other unsafe characters.
// Additionally, it **must** be URL safe without percent encoding. // Additionally, it **must** be URL safe without percent encoding.
let db_name = interim_namegen::default_generator() let db_name = phono_namegen::default_generator()
.with_separator('_') .with_separator('_')
.generate_name(NAME_LEN_WORDS); .generate_name(NAME_LEN_WORDS);
{ {

View file

@ -3,7 +3,7 @@ use axum::{
extract::State, extract::State,
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::workspace_user_perm::WorkspaceMembership; use phono_models::workspace_user_perm::WorkspaceMembership;
use crate::{ use crate::{
app::AppDbConn, app::AppDbConn,

View file

@ -3,11 +3,11 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::IntoResponse, response::IntoResponse,
}; };
use interim_models::{service_cred::ServiceCred, workspace::Workspace}; use phono_backends::{
use interim_pgtypes::{
escape_identifier, escape_identifier,
rolnames::{ROLE_PREFIX_SERVICE_CRED, SERVICE_CRED_CONN_LIMIT, SERVICE_CRED_SUFFIX_LEN}, rolnames::{ROLE_PREFIX_SERVICE_CRED, SERVICE_CRED_CONN_LIMIT, SERVICE_CRED_SUFFIX_LEN},
}; };
use phono_models::{service_cred::ServiceCred, workspace::Workspace};
use rand::distributions::{Alphanumeric, DistString}; use rand::distributions::{Alphanumeric, DistString};
use redact::Secret; use redact::Secret;
use serde::Deserialize; use serde::Deserialize;

View file

@ -2,7 +2,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::IntoResponse, response::IntoResponse,
}; };
use interim_pgtypes::{ use phono_backends::{
escape_identifier, escape_identifier,
rolnames::{ rolnames::{
ROLE_PREFIX_TABLE_OWNER, ROLE_PREFIX_TABLE_READER, ROLE_PREFIX_TABLE_WRITER, ROLE_PREFIX_TABLE_OWNER, ROLE_PREFIX_TABLE_READER, ROLE_PREFIX_TABLE_WRITER,
@ -42,7 +42,7 @@ pub(super) async fn post(
// FIXME: CSRF, Check workspace authorization. // FIXME: CSRF, Check workspace authorization.
const NAME_LEN_WORDS: usize = 3; const NAME_LEN_WORDS: usize = 3;
let table_name = interim_namegen::default_generator() let table_name = phono_namegen::default_generator()
.with_separator('_') .with_separator('_')
.generate_name(NAME_LEN_WORDS); .generate_name(NAME_LEN_WORDS);

View file

@ -4,7 +4,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::workspace::Workspace; use phono_models::workspace::Workspace;
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid; use uuid::Uuid;

View file

@ -6,8 +6,8 @@ use axum::{
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use futures::{lock::Mutex, prelude::*, stream}; use futures::{lock::Mutex, prelude::*, stream};
use interim_models::{service_cred::ServiceCred, workspace::Workspace}; use phono_backends::{pg_class::PgClass, pg_role::RoleTree};
use interim_pgtypes::{pg_class::PgClass, pg_role::RoleTree}; use phono_models::{service_cred::ServiceCred, workspace::Workspace};
use redact::Secret; use redact::Secret;
use serde::Deserialize; use serde::Deserialize;
use url::Url; use url::Url;

View file

@ -4,7 +4,7 @@ use axum::{
extract::{Path, State}, extract::{Path, State},
response::{Html, IntoResponse}, response::{Html, IntoResponse},
}; };
use interim_models::workspace::Workspace; use phono_models::workspace::Workspace;
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid; use uuid::Uuid;

View file

@ -7,8 +7,8 @@ use axum::{
}; };
use axum_extra::extract::Form; use axum_extra::extract::Form;
use futures::{lock::Mutex, prelude::*, stream}; use futures::{lock::Mutex, prelude::*, stream};
use interim_models::service_cred::ServiceCred; use phono_backends::{escape_identifier, pg_class::PgClass};
use interim_pgtypes::{escape_identifier, pg_class::PgClass}; use phono_models::service_cred::ServiceCred;
use serde::Deserialize; use serde::Deserialize;
use sqlx::query; use sqlx::query;
use uuid::Uuid; use uuid::Uuid;

View file

@ -22,7 +22,7 @@ pub(crate) struct Settings {
#[serde(default)] #[serde(default)]
pub(crate) dev: u8, pub(crate) dev: u8,
/// postgresql:// URL for Interim's application database. /// postgresql:// URL for Phonograph's application database.
pub(crate) database_url: Url, pub(crate) database_url: Url,
#[serde(default = "default_app_db_max_connections")] #[serde(default = "default_app_db_max_connections")]

View file

@ -11,7 +11,7 @@ use axum_extra::extract::{
CookieJar, CookieJar,
cookie::{Cookie, SameSite}, cookie::{Cookie, SameSite},
}; };
use interim_models::user::User; use phono_models::user::User;
use sqlx::query_as; use sqlx::query_as;
use uuid::Uuid; use uuid::Uuid;

View file

@ -1,8 +1,8 @@
use anyhow::Result; use anyhow::Result;
use askama::Template; use askama::Template;
use derive_builder::Builder; use derive_builder::Builder;
use interim_models::{client::AppDbClient, workspace::Workspace}; use phono_backends::client::WorkspaceClient;
use interim_pgtypes::client::WorkspaceClient; use phono_models::{client::AppDbClient, workspace::Workspace};
use sqlx::postgres::types::Oid; use sqlx::postgres::types::Oid;
use uuid::Uuid; use uuid::Uuid;

View file

@ -3,8 +3,8 @@ use std::{collections::HashMap, sync::Arc, time::Duration};
use anyhow::Result; use anyhow::Result;
use axum::extract::FromRef; use axum::extract::FromRef;
use derive_builder::Builder; use derive_builder::Builder;
use interim_models::{client::AppDbClient, workspace::Workspace}; use phono_backends::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER};
use interim_pgtypes::{client::WorkspaceClient, rolnames::ROLE_PREFIX_USER}; use phono_models::{client::AppDbClient, workspace::Workspace};
use sqlx::{Executor, PgPool, postgres::PgPoolOptions, raw_sql}; use sqlx::{Executor, PgPool, postgres::PgPoolOptions, raw_sql};
use tokio::sync::{OnceCell, RwLock}; use tokio::sync::{OnceCell, RwLock};
use uuid::Uuid; use uuid::Uuid;
@ -91,10 +91,10 @@ discard sequences;
/// should **NEVER** execute untrusted SQL. /// should **NEVER** execute untrusted SQL.
pub async fn acquire_for( pub async fn acquire_for(
&mut self, &mut self,
base_id: Uuid, workspace_id: Uuid,
set_role: RoleAssignment, set_role: RoleAssignment,
) -> Result<WorkspaceClient> { ) -> Result<WorkspaceClient> {
let pool = self.get_pool_for(base_id).await?; let pool = self.get_pool_for(workspace_id).await?;
let mut client = WorkspaceClient::from_pool_conn(pool.acquire().await?); let mut client = WorkspaceClient::from_pool_conn(pool.acquire().await?);
match set_role { match set_role {
RoleAssignment::User(uid) => { RoleAssignment::User(uid) => {
@ -107,15 +107,15 @@ discard sequences;
Ok(client) Ok(client)
} }
pub async fn close_for(&mut self, base_id: Uuid) -> Result<()> { pub async fn close_for(&mut self, workspace_id: Uuid) -> Result<()> {
let pools = self.pools.read().await; let pools = self.pools.read().await;
if let Some(cell) = pools.get(&base_id) if let Some(cell) = pools.get(&workspace_id)
&& let Some(pool) = cell.get() && let Some(pool) = cell.get()
{ {
let pool = pool.clone(); let pool = pool.clone();
drop(pools); // Release read lock drop(pools); // Release read lock
let mut pools = self.pools.write().await; let mut pools = self.pools.write().await;
pools.remove(&base_id); pools.remove(&workspace_id);
drop(pools); // Release write lock drop(pools); // Release write lock
pool.close().await; pool.close().await;
} }

View file

@ -1,12 +1,12 @@
//! This module is named with the `_utils` suffix to help differentiate it from //! This module is named with the `_utils` suffix to help differentiate it from
//! the [`interim_models::workspace`] module, which is also used extensively //! the [`phono_models::workspace`] module, which is also used extensively
//! across the server code. //! across the server code.
use interim_models::{client::AppDbClient, portal::Portal}; use phono_backends::{
use interim_pgtypes::{
client::WorkspaceClient, client::WorkspaceClient,
pg_class::{PgClass, PgRelKind}, pg_class::{PgClass, PgRelKind},
}; };
use phono_models::{client::AppDbClient, portal::Portal};
use uuid::Uuid; use uuid::Uuid;
pub const PHONO_TABLE_NAMESPACE: &str = "phono"; pub const PHONO_TABLE_NAMESPACE: &str = "phono";

Some files were not shown because too many files have changed in this diff Show more