Projects view by user
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { Response } from 'express';
|
||||
import { AuthenticatedRequest } from '../types';
|
||||
import * as concentratorService from '../services/concentrator.service';
|
||||
import { CreateConcentratorInput, UpdateConcentratorInput } from '../validators/concentrator.validator';
|
||||
|
||||
@@ -7,13 +8,14 @@ import { CreateConcentratorInput, UpdateConcentratorInput } from '../validators/
|
||||
* Get all concentrators with optional filters and pagination
|
||||
* Query params: project_id, status, page, limit, sortBy, sortOrder
|
||||
*/
|
||||
export async function getAll(req: Request, res: Response): Promise<void> {
|
||||
export async function getAll(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const { project_id, status, page, limit, sortBy, sortOrder } = req.query;
|
||||
const { project_id, status, type, page, limit, sortBy, sortOrder } = req.query;
|
||||
|
||||
const filters: concentratorService.ConcentratorFilters = {};
|
||||
if (project_id) filters.project_id = project_id as string;
|
||||
if (status) filters.status = status as string;
|
||||
if (type) filters.type = type as concentratorService.ConcentratorType;
|
||||
|
||||
const pagination: concentratorService.PaginationOptions = {
|
||||
page: page ? parseInt(page as string, 10) : 1,
|
||||
@@ -22,7 +24,13 @@ export async function getAll(req: Request, res: Response): Promise<void> {
|
||||
sortOrder: sortOrder as 'asc' | 'desc',
|
||||
};
|
||||
|
||||
const result = await concentratorService.getAll(filters, pagination);
|
||||
// Pass user info for role-based filtering
|
||||
const requestingUser = req.user ? {
|
||||
roleName: req.user.roleName,
|
||||
projectId: req.user.projectId
|
||||
} : undefined;
|
||||
|
||||
const result = await concentratorService.getAll(filters, pagination, requestingUser);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as readingService from '../services/reading.service';
|
||||
* List all meters with pagination and optional filtering
|
||||
* Query params: page, pageSize, concentrator_id, project_id, status, type, search
|
||||
*/
|
||||
export async function getAll(req: Request, res: Response): Promise<void> {
|
||||
export async function getAll(req: AuthenticatedRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const page = parseInt(req.query.page as string, 10) || 1;
|
||||
const pageSize = Math.min(parseInt(req.query.pageSize as string, 10) || 50, 1000);
|
||||
@@ -35,7 +35,13 @@ export async function getAll(req: Request, res: Response): Promise<void> {
|
||||
filters.search = req.query.search as string;
|
||||
}
|
||||
|
||||
const result = await meterService.getAll(filters, { page, pageSize });
|
||||
// Pass user info for role-based filtering
|
||||
const requestingUser = req.user ? {
|
||||
roleName: req.user.roleName,
|
||||
projectId: req.user.projectId
|
||||
} : undefined;
|
||||
|
||||
const result = await meterService.getAll(filters, { page, pageSize }, requestingUser);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -68,11 +68,13 @@ export interface PaginatedResult<T> {
|
||||
* Get all concentrators with optional filters and pagination
|
||||
* @param filters - Optional filter criteria
|
||||
* @param pagination - Optional pagination options
|
||||
* @param requestingUser - User making the request (for role-based filtering)
|
||||
* @returns Paginated list of concentrators
|
||||
*/
|
||||
export async function getAll(
|
||||
filters?: ConcentratorFilters,
|
||||
pagination?: PaginationOptions
|
||||
pagination?: PaginationOptions,
|
||||
requestingUser?: { roleName: string; projectId?: string | null }
|
||||
): Promise<PaginatedResult<Concentrator>> {
|
||||
const page = pagination?.page || 1;
|
||||
const limit = pagination?.limit || 10;
|
||||
@@ -85,7 +87,15 @@ export async function getAll(
|
||||
const params: unknown[] = [];
|
||||
let paramIndex = 1;
|
||||
|
||||
if (filters?.project_id) {
|
||||
// Role-based filtering: OPERATOR users can only see their assigned project
|
||||
if (requestingUser && requestingUser.roleName !== 'ADMIN' && requestingUser.projectId) {
|
||||
conditions.push(`project_id = $${paramIndex}`);
|
||||
params.push(requestingUser.projectId);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
// Additional filter by project_id (only applies if user is ADMIN or no user context)
|
||||
if (filters?.project_id && (!requestingUser || requestingUser.roleName === 'ADMIN')) {
|
||||
conditions.push(`project_id = $${paramIndex}`);
|
||||
params.push(filters.project_id);
|
||||
paramIndex++;
|
||||
|
||||
@@ -92,10 +92,14 @@ export interface UpdateMeterInput {
|
||||
|
||||
/**
|
||||
* Get all meters with optional filtering and pagination
|
||||
* @param filters - Optional filter criteria
|
||||
* @param pagination - Optional pagination options
|
||||
* @param requestingUser - User making the request (for role-based filtering)
|
||||
*/
|
||||
export async function getAll(
|
||||
filters?: MeterFilters,
|
||||
pagination?: PaginationParams
|
||||
pagination?: PaginationParams,
|
||||
requestingUser?: { roleName: string; projectId?: string | null }
|
||||
): Promise<PaginatedResult<MeterWithDetails>> {
|
||||
const page = pagination?.page || 1;
|
||||
const pageSize = pagination?.pageSize || 50;
|
||||
@@ -105,13 +109,21 @@ export async function getAll(
|
||||
const params: unknown[] = [];
|
||||
let paramIndex = 1;
|
||||
|
||||
// Role-based filtering: OPERATOR users can only see meters from their assigned project
|
||||
if (requestingUser && requestingUser.roleName !== 'ADMIN' && requestingUser.projectId) {
|
||||
conditions.push(`c.project_id = $${paramIndex}`);
|
||||
params.push(requestingUser.projectId);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (filters?.concentrator_id) {
|
||||
conditions.push(`m.concentrator_id = $${paramIndex}`);
|
||||
params.push(filters.concentrator_id);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (filters?.project_id) {
|
||||
// Additional filter by project_id (only applies if user is ADMIN or no user context)
|
||||
if (filters?.project_id && (!requestingUser || requestingUser.roleName === 'ADMIN')) {
|
||||
conditions.push(`c.project_id = $${paramIndex}`);
|
||||
params.push(filters.project_id);
|
||||
paramIndex++;
|
||||
|
||||
@@ -93,6 +93,7 @@ export async function getAll(
|
||||
u.role_id,
|
||||
r.name as role_name,
|
||||
r.description as role_description,
|
||||
u.project_id,
|
||||
u.is_active,
|
||||
u.last_login,
|
||||
u.created_at,
|
||||
@@ -122,6 +123,7 @@ export async function getAll(
|
||||
updated_at: row.updated_at,
|
||||
}
|
||||
: undefined,
|
||||
project_id: row.project_id,
|
||||
is_active: row.is_active,
|
||||
last_login: row.last_login,
|
||||
created_at: row.created_at,
|
||||
@@ -160,6 +162,7 @@ export async function getById(id: string): Promise<UserPublic | null> {
|
||||
r.name as role_name,
|
||||
r.description as role_description,
|
||||
r.permissions as role_permissions,
|
||||
u.project_id,
|
||||
u.is_active,
|
||||
u.last_login,
|
||||
u.created_at,
|
||||
@@ -192,6 +195,7 @@ export async function getById(id: string): Promise<UserPublic | null> {
|
||||
updated_at: row.updated_at,
|
||||
}
|
||||
: undefined,
|
||||
project_id: row.project_id,
|
||||
is_active: row.is_active,
|
||||
last_login: row.last_login,
|
||||
created_at: row.created_at,
|
||||
@@ -235,6 +239,7 @@ export async function create(data: {
|
||||
name: string;
|
||||
avatar_url?: string | null;
|
||||
role_id: string;
|
||||
project_id?: string | null;
|
||||
is_active?: boolean;
|
||||
}): Promise<UserPublic> {
|
||||
// Check if email already exists
|
||||
@@ -248,9 +253,9 @@ export async function create(data: {
|
||||
|
||||
const result = await query(
|
||||
`
|
||||
INSERT INTO users (email, password_hash, name, avatar_url, role_id, is_active)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING id, email, name, avatar_url, role_id, is_active, last_login, created_at, updated_at
|
||||
INSERT INTO users (email, password_hash, name, avatar_url, role_id, project_id, is_active)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id, email, name, avatar_url, role_id, project_id, is_active, last_login, created_at, updated_at
|
||||
`,
|
||||
[
|
||||
data.email.toLowerCase(),
|
||||
@@ -258,6 +263,7 @@ export async function create(data: {
|
||||
data.name,
|
||||
data.avatar_url ?? null,
|
||||
data.role_id,
|
||||
data.project_id ?? null,
|
||||
data.is_active ?? true,
|
||||
]
|
||||
);
|
||||
@@ -281,6 +287,7 @@ export async function update(
|
||||
name?: string;
|
||||
avatar_url?: string | null;
|
||||
role_id?: string;
|
||||
project_id?: string | null;
|
||||
is_active?: boolean;
|
||||
}
|
||||
): Promise<UserPublic | null> {
|
||||
@@ -327,6 +334,12 @@ export async function update(
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (data.project_id !== undefined) {
|
||||
updates.push(`project_id = $${paramIndex}`);
|
||||
params.push(data.project_id);
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
if (data.is_active !== undefined) {
|
||||
updates.push(`is_active = $${paramIndex}`);
|
||||
params.push(data.is_active);
|
||||
|
||||
Reference in New Issue
Block a user