qa: shared instances post release (#6893)

* fix: 20 user cap

* qa: invite modal dropdown + other + clamp limits

* fix: hide filters if just one type

* feat: update req banner

* feat: invite management frontend

* fix: moderation issues with shared instances

* feat: instance icon improvements

* fix: better offline handling

* fix: lint

* feat: show avatar in install to play modal

* feat: smaller qa points

* fix: fmt

* fix: fmt

* fix: yeet svg

* fix: 50 user limit
This commit is contained in:
Calum H.
2026-07-28 14:10:12 +00:00
committed by GitHub
parent 5d34e7902a
commit 82348fe40a
61 changed files with 1809 additions and 307 deletions
+85 -2
View File
@@ -4,6 +4,7 @@ use crate::database::models::ids::*;
use crate::database::models::notifications_template_item::{
NotificationTemplate, get_or_set_cached_dynamic_html,
};
use crate::database::models::report_item::DBReport;
use crate::database::models::{
DBOrganization, DBProject, DBUser, DatabaseError,
};
@@ -11,10 +12,12 @@ use crate::env::ENV;
use crate::models::v3::notifications::NotificationBody;
use crate::routes::ApiError;
use crate::util::error::Context;
use crate::util::http::HTTP_CLIENT;
use ariadne::ids::base62_impl::to_base62;
use futures::TryFutureExt;
use lettre::Message;
use lettre::message::{Mailbox, MultiPart, SinglePart};
use serde::Deserialize;
use sqlx::query;
use std::collections::HashMap;
use std::time::Duration;
@@ -312,6 +315,70 @@ enum EmailTemplate {
},
}
#[derive(Deserialize)]
struct SharedInstance {
name: String,
}
async fn resolve_report_title(
exec: &mut PgTransaction<'_>,
report_id: DBReportId,
title: String,
) -> Result<String, ApiError> {
if title != "unknown" {
return Ok(title);
}
let Some(report) = DBReport::get(report_id, &mut *exec).await? else {
return Ok(title);
};
let Some(shared_instance_id) = report.shared_instance_id else {
return Ok(title);
};
let instance_id = to_base62(shared_instance_id.0 as u64);
let with_version = |name: String| match report.shared_instance_version_id {
Some(version) => format!("{name} (version {version})"),
None => name,
};
let fallback = with_version(format!("shared instance {instance_id}"));
let response = HTTP_CLIENT
.get(format!(
"{}/v1/instances/{instance_id}",
ENV.SHARED_INSTANCES_URL
))
.bearer_auth(&ENV.SHARED_INSTANCES_KEY)
.send()
.await
.and_then(reqwest::Response::error_for_status);
let response = match response {
Ok(response) => response,
Err(error) => {
warn!(
%error,
report_id = report_id.0,
%instance_id,
"Failed to fetch shared instance name for report email"
);
return Ok(fallback);
}
};
match response.json::<SharedInstance>().await {
Ok(instance) => Ok(with_version(instance.name)),
Err(error) => {
warn!(
%error,
report_id = report_id.0,
%instance_id,
"Failed to parse shared instance name for report email"
);
Ok(fallback)
}
}
}
async fn collect_template_variables(
exec: &mut PgTransaction<'_>,
redis: &RedisPool,
@@ -359,7 +426,15 @@ async fn collect_template_variables(
.await?;
map.insert(REPORT_ID, to_base62(report_id.0));
map.insert(REPORT_TITLE, result.title);
map.insert(
REPORT_TITLE,
resolve_report_title(
exec,
DBReportId(report_id.0 as i64),
result.title,
)
.await?,
);
map.insert(REPORT_DATE, date_human_readable(result.created));
Ok(EmailTemplate::Static(map))
}
@@ -380,7 +455,15 @@ async fn collect_template_variables(
.fetch_one(&mut *exec)
.await?;
map.insert(REPORT_TITLE, result.title);
map.insert(
REPORT_TITLE,
resolve_report_title(
exec,
DBReportId(report_id.0 as i64),
result.title,
)
.await?,
);
map.insert(NEWREPORT_ID, to_base62(report_id.0));
Ok(EmailTemplate::Static(map))
}
+1 -4
View File
@@ -60,16 +60,13 @@ pub async fn report_create(
pub struct ReportsRequestOptions {
#[serde(default = "default_count")]
count: u16,
#[serde(default = "default_all")]
#[serde(default)]
all: bool,
}
fn default_count() -> u16 {
100
}
fn default_all() -> bool {
true
}
/// Get open reports for the current user.
#[utoipa::path(
+1 -4
View File
@@ -320,16 +320,13 @@ pub struct ReportsRequestOptions {
pub count: u16,
#[serde(default)]
pub offset: u32,
#[serde(default = "default_all")]
#[serde(default)]
pub all: bool,
}
fn default_count() -> u16 {
100
}
fn default_all() -> bool {
true
}
#[utoipa::path(
tag = "reports",