diff --git a/backend/app/api/v1/attachments.py b/backend/app/api/v1/attachments.py index 6cbdb00a..0c90bfc7 100644 --- a/backend/app/api/v1/attachments.py +++ b/backend/app/api/v1/attachments.py @@ -15,6 +15,7 @@ from app.crud import user as user_crud from app.crud import member as member_crud from app.core.security import decode_token from app.schemas.attachment import AttachmentRead +from app.schemas.user import UserDisplay router = APIRouter() global_router = APIRouter() @@ -74,7 +75,14 @@ async def upload_attachment( operator_id=current_user.id, operator_role=current_user.role, ) - return attachment + return AttachmentRead( + id=attachment.id, + filename=attachment.filename, + file_size=attachment.file_size, + uploaded_by=UserDisplay.model_validate(current_user) if current_user else None, + uploaded_by_id=attachment.uploaded_by, + uploaded_at=attachment.uploaded_at, + ) @router.get( @@ -90,7 +98,22 @@ async def list_attachments( ) -> list[AttachmentRead]: await _ensure_study_exists(db, study_id) attachments = await attachment_crud.list_attachments(db, study_id, entity_type, entity_id) - return list(attachments) + user_ids = {a.uploaded_by for a in attachments if a.uploaded_by} + users_map = await user_crud.get_users_by_ids(db, user_ids) + result: list[AttachmentRead] = [] + for a in attachments: + user = users_map.get(a.uploaded_by) + result.append( + AttachmentRead( + id=a.id, + filename=a.filename, + file_size=a.file_size, + uploaded_by=UserDisplay.model_validate(user) if user else None, + uploaded_by_id=a.uploaded_by, + uploaded_at=a.uploaded_at, + ) + ) + return result @router.get( diff --git a/backend/app/api/v1/members.py b/backend/app/api/v1/members.py index 31e1e3f1..720c4561 100644 --- a/backend/app/api/v1/members.py +++ b/backend/app/api/v1/members.py @@ -6,7 +6,9 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_db_session, require_study_member, require_study_roles from app.crud import member as member_crud from app.crud import study as study_crud -from app.schemas.member import StudyMemberCreate, StudyMemberRead, StudyMemberUpdate +from app.crud import user as user_crud +from app.schemas.member import StudyMemberCreate, StudyMemberRead, StudyMemberReadWithUser, StudyMemberUpdate +from app.schemas.user import UserDisplay router = APIRouter() @@ -39,7 +41,7 @@ async def add_member( @router.get( "/", - response_model=list[StudyMemberRead], + response_model=list[StudyMemberReadWithUser], dependencies=[Depends(require_study_member())], ) async def list_members( @@ -47,10 +49,31 @@ async def list_members( skip: int = 0, limit: int = 100, db: AsyncSession = Depends(get_db_session), -) -> list[StudyMemberRead]: +) -> list[StudyMemberReadWithUser]: await _ensure_study_exists(db, study_id) members = await member_crud.list_members(db, study_id, skip=skip, limit=limit) - return list(members) + user_ids = {m.user_id for m in members} + users_map = await user_crud.get_users_by_ids(db, user_ids) + result: list[StudyMemberReadWithUser] = [] + for m in members: + # 仅返回项目内启用的成员 + 账号启用的用户 + if not m.is_active: + continue + user = users_map.get(m.user_id) + if not user or not user.is_active: + continue + result.append( + StudyMemberReadWithUser( + id=m.id, + study_id=m.study_id, + user_id=m.user_id, + role_in_study=m.role_in_study, + is_active=m.is_active, + added_at=m.added_at, + user=UserDisplay.model_validate(user) if user else None, + ) + ) + return result @router.patch( diff --git a/backend/app/api/v1/milestones.py b/backend/app/api/v1/milestones.py index ba6ffb60..a69860b8 100644 --- a/backend/app/api/v1/milestones.py +++ b/backend/app/api/v1/milestones.py @@ -7,7 +7,11 @@ from app.core.deps import get_current_user, get_db_session, require_study_member from app.crud import audit as audit_crud from app.crud import milestone as milestone_crud from app.crud import study as study_crud +from app.crud import user as user_crud +from app.crud import site as site_crud from app.schemas.milestone import MilestoneCreate, MilestoneRead, MilestoneUpdate +from app.schemas.user import UserDisplay +from app.schemas.milestone import SiteDisplay router = APIRouter() @@ -33,6 +37,12 @@ async def create_milestone( ) -> MilestoneRead: await _ensure_study_exists(db, study_id) milestone = await milestone_crud.create(db, study_id, milestone_in) + owner = None + site = None + if milestone.owner_id: + owner = await user_crud.get_by_id(db, milestone.owner_id) + if milestone.site_id: + site = await site_crud.get_site(db, milestone.site_id) await audit_crud.log_action( db, study_id=study_id, @@ -43,7 +53,22 @@ async def create_milestone( operator_id=current_user.id, operator_role=current_user.role, ) - return milestone + return MilestoneRead( + id=milestone.id, + study_id=milestone.study_id, + type=milestone.type, + name=milestone.name, + planned_date=milestone.planned_date, + actual_date=milestone.actual_date, + status=milestone.status, + owner_id=milestone.owner_id, + site_id=milestone.site_id, + owner=UserDisplay.model_validate(owner) if owner else None, + site=SiteDisplay.model_validate(site) if site else None, + notes=milestone.notes, + created_at=milestone.created_at, + updated_at=milestone.updated_at, + ) @router.get( @@ -57,7 +82,33 @@ async def list_milestones( ) -> list[MilestoneRead]: await _ensure_study_exists(db, study_id) milestones = await milestone_crud.list_milestones(db, study_id) - return list(milestones) + owner_ids = {m.owner_id for m in milestones if m.owner_id} + site_ids = {m.site_id for m in milestones if m.site_id} + users_map = await user_crud.get_users_by_ids(db, owner_ids) + sites_map = await site_crud.get_sites_by_ids(db, site_ids) + result: list[MilestoneRead] = [] + for m in milestones: + owner = users_map.get(m.owner_id) + site = sites_map.get(m.site_id) + result.append( + MilestoneRead( + id=m.id, + study_id=m.study_id, + type=m.type, + name=m.name, + planned_date=m.planned_date, + actual_date=m.actual_date, + status=m.status, + owner_id=m.owner_id, + site_id=m.site_id, + owner=UserDisplay.model_validate(owner) if owner else None, + site=SiteDisplay.model_validate(site) if site else None, + notes=m.notes, + created_at=m.created_at, + updated_at=m.updated_at, + ) + ) + return result @router.patch( @@ -78,6 +129,12 @@ async def update_milestone( raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Milestone not found") old_status = milestone.status updated = await milestone_crud.update(db, milestone, milestone_in) + owner = None + site = None + if updated.owner_id: + owner = await user_crud.get_by_id(db, updated.owner_id) + if updated.site_id: + site = await site_crud.get_site(db, updated.site_id) detail = None if milestone_in.status and milestone_in.status != old_status: detail = f"milestone {milestone_id} status {old_status} -> {milestone_in.status}" @@ -91,4 +148,19 @@ async def update_milestone( operator_id=current_user.id, operator_role=current_user.role, ) - return updated + return MilestoneRead( + id=updated.id, + study_id=updated.study_id, + type=updated.type, + name=updated.name, + planned_date=updated.planned_date, + actual_date=updated.actual_date, + status=updated.status, + owner_id=updated.owner_id, + site_id=updated.site_id, + owner=UserDisplay.model_validate(owner) if owner else None, + site=SiteDisplay.model_validate(site) if site else None, + notes=updated.notes, + created_at=updated.created_at, + updated_at=updated.updated_at, + ) diff --git a/backend/app/api/v1/tasks.py b/backend/app/api/v1/tasks.py index 5cead312..4d922285 100644 --- a/backend/app/api/v1/tasks.py +++ b/backend/app/api/v1/tasks.py @@ -8,7 +8,9 @@ from app.crud import audit as audit_crud from app.crud import milestone as milestone_crud from app.crud import study as study_crud from app.crud import task as task_crud +from app.crud import user as user_crud from app.schemas.task import TaskCreate, TaskRead, TaskUpdate +from app.schemas.user import UserDisplay router = APIRouter() @@ -47,6 +49,9 @@ async def create_task( await _ensure_study_exists(db, study_id) await _validate_milestone(db, study_id, task_in.milestone_id) task = await task_crud.create(db, study_id, task_in, created_by=current_user.id) + assignee = None + if task.assignee_id: + assignee = await user_crud.get_by_id(db, task.assignee_id) await audit_crud.log_action( db, study_id=study_id, @@ -57,7 +62,7 @@ async def create_task( operator_id=current_user.id, operator_role=current_user.role, ) - return task + return _to_task_read(task, assignee) @router.get( @@ -74,7 +79,13 @@ async def list_tasks( ) -> list[TaskRead]: await _ensure_study_exists(db, study_id) tasks = await task_crud.list_tasks(db, study_id, milestone_id=milestone_id, assignee_id=assignee_id, status=status) - return list(tasks) + assignee_ids = {t.assignee_id for t in tasks if t.assignee_id} + users_map = await user_crud.get_users_by_ids(db, assignee_ids) + result: list[TaskRead] = [] + for t in tasks: + user = users_map.get(t.assignee_id) + result.append(_to_task_read(t, user)) + return result @router.patch( @@ -98,6 +109,9 @@ async def update_task( old_status = task.status updated = await task_crud.update(db, task, task_in) + assignee = None + if updated.assignee_id: + assignee = await user_crud.get_by_id(db, updated.assignee_id) detail = None if task_in.status and task_in.status != old_status: detail = f"task {task_id} status {old_status} -> {task_in.status}" @@ -111,4 +125,23 @@ async def update_task( operator_id=current_user.id, operator_role=current_user.role, ) - return updated + return _to_task_read(updated, assignee) + + +def _to_task_read(task, assignee) -> TaskRead: + return TaskRead( + id=task.id, + study_id=task.study_id, + milestone_id=task.milestone_id, + title=task.title, + description=task.description, + assignee_id=task.assignee_id, + assignee=UserDisplay.model_validate(assignee) if assignee else None, + priority=task.priority, + due_date=task.due_date, + status=task.status, + completed_at=task.completed_at, + created_by=task.created_by, + created_at=task.created_at, + updated_at=task.updated_at, + ) diff --git a/backend/app/crud/milestone.py b/backend/app/crud/milestone.py index 3cec213d..0ee1b593 100644 --- a/backend/app/crud/milestone.py +++ b/backend/app/crud/milestone.py @@ -17,6 +17,7 @@ async def create(db: AsyncSession, study_id: uuid.UUID, milestone_in: MilestoneC actual_date=None, status=milestone_in.status or "NOT_STARTED", owner_id=milestone_in.owner_id, + site_id=milestone_in.site_id, notes=milestone_in.notes, ) db.add(milestone) diff --git a/backend/app/crud/site.py b/backend/app/crud/site.py index 69b79ed4..db892324 100644 --- a/backend/app/crud/site.py +++ b/backend/app/crud/site.py @@ -46,3 +46,11 @@ async def list_by_study(db: AsyncSession, study_id: uuid.UUID, skip: int = 0, li select(Site).where(Site.study_id == study_id).offset(skip).limit(limit) ) return result.scalars().all() + + +async def get_sites_by_ids(db: AsyncSession, ids: set[uuid.UUID]) -> dict[uuid.UUID, Site]: + if not ids: + return {} + result = await db.execute(select(Site).where(Site.id.in_(ids))) + sites = result.scalars().all() + return {s.id: s for s in sites} diff --git a/backend/app/crud/user.py b/backend/app/crud/user.py index 4d2397b5..1acdbd67 100644 --- a/backend/app/crud/user.py +++ b/backend/app/crud/user.py @@ -73,6 +73,14 @@ async def ensure_admin_exists(db: AsyncSession, *, default_password: str = "admi await db.commit() +async def get_users_by_ids(db: AsyncSession, ids: set[uuid.UUID]) -> dict[uuid.UUID, User]: + if not ids: + return {} + result = await db.execute(select(User).where(User.id.in_(ids))) + users = result.scalars().all() + return {u.id: u for u in users} + + async def delete_user(db: AsyncSession, user: User) -> None: await db.execute(delete(StudyMember).where(StudyMember.user_id == user.id)) await db.delete(user) diff --git a/backend/app/models/milestone.py b/backend/app/models/milestone.py index ec8030f3..20d5f1f2 100644 --- a/backend/app/models/milestone.py +++ b/backend/app/models/milestone.py @@ -18,6 +18,7 @@ class Milestone(Base): planned_date: Mapped[date | None] = mapped_column(Date, nullable=True) actual_date: Mapped[date | None] = mapped_column(Date, nullable=True) status: Mapped[str] = mapped_column(String(20), nullable=False, default="NOT_STARTED") + site_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), nullable=True) owner_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) notes: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) diff --git a/backend/app/schemas/attachment.py b/backend/app/schemas/attachment.py index c531d5fb..a71e7f71 100644 --- a/backend/app/schemas/attachment.py +++ b/backend/app/schemas/attachment.py @@ -1,14 +1,17 @@ import uuid from datetime import datetime -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field + +from app.schemas.user import UserDisplay class AttachmentRead(BaseModel): id: uuid.UUID filename: str - file_size: int - uploaded_by: uuid.UUID + file_size: int = Field(alias="size") + uploaded_by: UserDisplay | None = None + uploaded_by_id: uuid.UUID | None = None uploaded_at: datetime - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(from_attributes=True, populate_by_name=True) diff --git a/backend/app/schemas/member.py b/backend/app/schemas/member.py index 35654de1..37d94523 100644 --- a/backend/app/schemas/member.py +++ b/backend/app/schemas/member.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import Literal, Optional from pydantic import BaseModel, ConfigDict, Field +from app.schemas.user import UserDisplay StudyRole = Literal["PM", "CRA", "PV", "IMP", "ADMIN"] @@ -27,3 +28,7 @@ class StudyMemberRead(BaseModel): added_at: datetime model_config = ConfigDict(from_attributes=True) + + +class StudyMemberReadWithUser(StudyMemberRead): + user: Optional[UserDisplay] = None diff --git a/backend/app/schemas/milestone.py b/backend/app/schemas/milestone.py index 8a711a7e..574d0f78 100644 --- a/backend/app/schemas/milestone.py +++ b/backend/app/schemas/milestone.py @@ -4,12 +4,21 @@ from typing import Optional from pydantic import BaseModel, ConfigDict, Field +from app.schemas.user import UserDisplay + + +class SiteDisplay(BaseModel): + id: uuid.UUID + name: Optional[str] = None + + model_config = ConfigDict(from_attributes=True) class MilestoneCreate(BaseModel): type: str name: Optional[str] = None planned_date: Optional[date] = None owner_id: Optional[uuid.UUID] = None + site_id: Optional[uuid.UUID] = None notes: Optional[str] = None status: str = Field(default="NOT_STARTED") @@ -20,6 +29,7 @@ class MilestoneUpdate(BaseModel): actual_date: Optional[date] = None status: Optional[str] = None owner_id: Optional[uuid.UUID] = None + site_id: Optional[uuid.UUID] = None notes: Optional[str] = None @@ -32,6 +42,9 @@ class MilestoneRead(BaseModel): actual_date: Optional[date] status: str owner_id: Optional[uuid.UUID] + site_id: Optional[uuid.UUID] = None + owner: Optional[UserDisplay] = None + site: Optional[SiteDisplay] = None notes: Optional[str] created_at: datetime updated_at: datetime diff --git a/backend/app/schemas/task.py b/backend/app/schemas/task.py index 6816fb9a..49000471 100644 --- a/backend/app/schemas/task.py +++ b/backend/app/schemas/task.py @@ -4,6 +4,8 @@ from typing import Optional from pydantic import BaseModel, ConfigDict +from app.schemas.user import UserDisplay + class TaskCreate(BaseModel): milestone_id: Optional[uuid.UUID] = None @@ -31,6 +33,7 @@ class TaskRead(BaseModel): title: str description: Optional[str] assignee_id: Optional[uuid.UUID] + assignee: Optional[UserDisplay] = None priority: str due_date: Optional[date] status: str diff --git a/backend/app/schemas/user.py b/backend/app/schemas/user.py index 10609bc1..93f95b23 100644 --- a/backend/app/schemas/user.py +++ b/backend/app/schemas/user.py @@ -7,6 +7,14 @@ from pydantic import BaseModel, ConfigDict, Field UserRole = Literal["PM", "CRA", "PV", "IMP", "ADMIN"] +class UserDisplay(BaseModel): + id: uuid.UUID + username: str + display_name: Optional[str] = None + + model_config = ConfigDict(from_attributes=True) + + class UserBase(BaseModel): username: str = Field(min_length=1) role: UserRole diff --git a/backend/app/uploads/study_44444444-4444-4444-4444-444444444444/ethics_node_d9e8057a-8c9c-4b9c-a94a-dbc91301c13c/7c381eef-241c-434a-be64-bc9f5a7ab42f.xlsx b/backend/app/uploads/study_44444444-4444-4444-4444-444444444444/ethics_node_d9e8057a-8c9c-4b9c-a94a-dbc91301c13c/7c381eef-241c-434a-be64-bc9f5a7ab42f.xlsx new file mode 100644 index 00000000..892884c3 Binary files /dev/null and b/backend/app/uploads/study_44444444-4444-4444-4444-444444444444/ethics_node_d9e8057a-8c9c-4b9c-a94a-dbc91301c13c/7c381eef-241c-434a-be64-bc9f5a7ab42f.xlsx differ diff --git a/frontend/src/components/CommentList.vue b/frontend/src/components/CommentList.vue index f7d16f6a..5575cbf2 100644 --- a/frontend/src/components/CommentList.vue +++ b/frontend/src/components/CommentList.vue @@ -14,9 +14,9 @@ - +
- {{ c.created_by }} + {{ displayUser(c.created_by, { users: userMap, members: memberMap }) }}

{{ c.content }}

@@ -25,10 +25,12 @@ diff --git a/frontend/src/views/Milestones.vue b/frontend/src/views/Milestones.vue index 53adcd37..56a8cdbc 100644 --- a/frontend/src/views/Milestones.vue +++ b/frontend/src/views/Milestones.vue @@ -33,12 +33,12 @@ @@ -63,20 +63,18 @@ :milestone="editingMilestone" :sites="sites" :members="members" - :users="users" @success="loadMilestones" /> diff --git a/frontend/src/views/Verification.vue b/frontend/src/views/Verification.vue index 310d1736..dc6a8b2d 100644 --- a/frontend/src/views/Verification.vue +++ b/frontend/src/views/Verification.vue @@ -18,7 +18,14 @@ - + @@ -60,16 +67,21 @@ import { computed, onMounted, ref } from "vue"; import { ElMessage } from "element-plus"; import { fetchVerifications, upsertVerification } from "../api/verifications"; +import { fetchSubjects } from "../api/subjects"; +import { listMembers } from "../api/members"; import { useStudyStore } from "../store/study"; import { useAuthStore } from "../store/auth"; import VerificationTable from "../components/VerificationTable.vue"; import SiteSelect from "../components/selectors/SiteSelect.vue"; import SubjectSelect from "../components/selectors/SubjectSelect.vue"; +import { displayDate } from "../utils/display"; const study = useStudyStore(); const auth = useAuthStore(); const verifications = ref([]); +const subjects = ref([]); +const members = ref([]); const loading = ref(false); const submitting = ref(false); const showEdit = ref(false); @@ -144,10 +156,46 @@ const submitEdit = async () => { } }; +const loadSubjects = async () => { + if (!study.currentStudy) return; + try { + const { data } = await fetchSubjects(study.currentStudy.id, { limit: 1000 }); + subjects.value = data.items || data || []; + } catch { + subjects.value = []; + } +}; + +const loadMembers = async () => { + if (!study.currentStudy) return; + try { + const { data } = await listMembers(study.currentStudy.id, { limit: 500 }); + members.value = Array.isArray(data) ? data : data.items || []; + } catch { + members.value = []; + } +}; + +const subjectMap = computed(() => + subjects.value.reduce>((acc, cur) => { + if (cur?.id) acc[cur.id] = cur.subject_no || cur.id; + return acc; + }, {}) +); + +const verifierMap = computed(() => + members.value.reduce>((acc, cur) => { + const username = cur?.user?.display_name || cur?.user?.username || cur?.username; + if (cur?.user_id) acc[cur.user_id] = username || cur.user_id; + return acc; + }, {}) +); + onMounted(async () => { if (!auth.user && auth.token) { await auth.fetchMe().catch(() => {}); } + await Promise.all([loadSubjects(), loadMembers()]); load(); }); diff --git a/frontend/src/views/admin/AuditLogs.vue b/frontend/src/views/admin/AuditLogs.vue index 6bd278f9..dc4a3f7c 100644 --- a/frontend/src/views/admin/AuditLogs.vue +++ b/frontend/src/views/admin/AuditLogs.vue @@ -44,14 +44,19 @@ - + + + @@ -94,6 +99,7 @@ import { useAuthStore } from "../../store/auth"; import { roleDict, getDictLabel } from "../../dictionaries"; import { exportAuditCsv } from "../../audit/export/auditExportService"; import { logAudit } from "../../audit"; +import { displayDateTime } from "../../utils/display"; const study = useStudyStore(); const auth = useAuthStore(); diff --git a/pg_data/base/16384/16399 b/pg_data/base/16384/16399 index c1322570..4a389152 100644 Binary files a/pg_data/base/16384/16399 and b/pg_data/base/16384/16399 differ diff --git a/pg_data/base/16384/16433 b/pg_data/base/16384/16433 index b365fd7b..5886d2d2 100644 Binary files a/pg_data/base/16384/16433 and b/pg_data/base/16384/16433 differ diff --git a/pg_data/base/16384/16445 b/pg_data/base/16384/16445 index 407fc407..dd797956 100644 Binary files a/pg_data/base/16384/16445 and b/pg_data/base/16384/16445 differ diff --git a/pg_data/base/16384/16483 b/pg_data/base/16384/16483 index b62837ca..cbf3a3d1 100644 Binary files a/pg_data/base/16384/16483 and b/pg_data/base/16384/16483 differ diff --git a/pg_data/base/16384/16508 b/pg_data/base/16384/16508 index 421f1733..cb8d8e2c 100644 Binary files a/pg_data/base/16384/16508 and b/pg_data/base/16384/16508 differ diff --git a/pg_data/base/16384/16520 b/pg_data/base/16384/16520 index 7ef7f73b..2958cba0 100644 Binary files a/pg_data/base/16384/16520 and b/pg_data/base/16384/16520 differ diff --git a/pg_data/base/16384/16531 b/pg_data/base/16384/16531 index 34e927d0..82afa407 100644 Binary files a/pg_data/base/16384/16531 and b/pg_data/base/16384/16531 differ diff --git a/pg_data/base/16384/16541 b/pg_data/base/16384/16541 index e3b16e95..c07bc33d 100644 Binary files a/pg_data/base/16384/16541 and b/pg_data/base/16384/16541 differ diff --git a/pg_data/base/16384/16595 b/pg_data/base/16384/16595 index cd5fbff9..b0a4e48d 100644 Binary files a/pg_data/base/16384/16595 and b/pg_data/base/16384/16595 differ diff --git a/pg_data/base/16384/16596 b/pg_data/base/16384/16596 index 1fdbb318..cb7f1b15 100644 Binary files a/pg_data/base/16384/16596 and b/pg_data/base/16384/16596 differ diff --git a/pg_data/base/16384/16597 b/pg_data/base/16384/16597 index 4be1b03d..ca908547 100644 Binary files a/pg_data/base/16384/16597 and b/pg_data/base/16384/16597 differ diff --git a/pg_data/global/pg_control b/pg_data/global/pg_control index c6079c60..ffab41c1 100644 Binary files a/pg_data/global/pg_control and b/pg_data/global/pg_control differ diff --git a/pg_data/pg_subtrans/0000 b/pg_data/pg_subtrans/0000 index 6d17cf9d..76af23b1 100644 Binary files a/pg_data/pg_subtrans/0000 and b/pg_data/pg_subtrans/0000 differ diff --git a/pg_data/pg_wal/000000010000000000000001 b/pg_data/pg_wal/000000010000000000000001 index 2be75570..9be87d3e 100644 Binary files a/pg_data/pg_wal/000000010000000000000001 and b/pg_data/pg_wal/000000010000000000000001 differ diff --git a/pg_data/pg_xact/0000 b/pg_data/pg_xact/0000 index 1ff89203..68f9957b 100644 Binary files a/pg_data/pg_xact/0000 and b/pg_data/pg_xact/0000 differ