mirror of
https://github.com/soconnor0919/hristudio.git
synced 2025-12-15 08:34:44 -05:00
feat: Enhance plugin store and experiment design infrastructure
- Add plugin store system with dynamic loading of robot actions - Implement plugin store API routes and database schema - Update experiment designer to support plugin-based actions - Refactor environment configuration and sidebar navigation - Improve authentication session handling with additional user details - Update Tailwind CSS configuration and global styles - Remove deprecated files and consolidate project structure
This commit is contained in:
376
docs/development.md
Normal file
376
docs/development.md
Normal file
@@ -0,0 +1,376 @@
|
||||
# Development Guidelines
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the development practices, coding standards, and workflow guidelines for contributing to HRIStudio. Following these guidelines ensures consistency and maintainability across the codebase.
|
||||
|
||||
## Development Environment
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js (v18+)
|
||||
- PostgreSQL (v14+)
|
||||
- Docker (for local development)
|
||||
- VS Code (recommended)
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Clone the Repository:**
|
||||
```bash
|
||||
git clone https://github.com/yourusername/hristudio.git
|
||||
cd hristudio
|
||||
```
|
||||
|
||||
2. **Install Dependencies:**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. **Environment Configuration:**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your local settings
|
||||
```
|
||||
|
||||
4. **Database Setup:**
|
||||
```bash
|
||||
npm run docker:up # Start PostgreSQL container
|
||||
npm run db:push # Apply database schema
|
||||
npm run db:seed # Seed initial data
|
||||
```
|
||||
|
||||
5. **Start Development Server:**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Code Organization
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── app/ # Next.js pages and layouts
|
||||
├── components/ # React components
|
||||
│ ├── auth/ # Authentication components
|
||||
│ ├── experiments/ # Experiment-related components
|
||||
│ ├── layout/ # Layout components
|
||||
│ ├── navigation/ # Navigation components
|
||||
│ ├── studies/ # Study-related components
|
||||
│ └── ui/ # Shared UI components
|
||||
├── lib/ # Utility functions and shared logic
|
||||
│ ├── experiments/ # Experiment-related utilities
|
||||
│ ├── permissions/ # Permission checking utilities
|
||||
│ └── plugin-store/ # Plugin store implementation
|
||||
├── server/ # Server-side code
|
||||
│ ├── api/ # tRPC routers
|
||||
│ ├── auth/ # Authentication configuration
|
||||
│ └── db/ # Database schemas and utilities
|
||||
└── styles/ # Global styles and Tailwind config
|
||||
```
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
1. **Files and Directories:**
|
||||
```typescript
|
||||
// Components
|
||||
components/auth/sign-in-form.tsx
|
||||
components/studies/study-card.tsx
|
||||
|
||||
// Pages
|
||||
app/dashboard/studies/[id]/page.tsx
|
||||
app/dashboard/experiments/new/page.tsx
|
||||
```
|
||||
|
||||
2. **Component Names:**
|
||||
```typescript
|
||||
// PascalCase for component names
|
||||
export function SignInForm() { ... }
|
||||
export function StudyCard() { ... }
|
||||
```
|
||||
|
||||
3. **Variables and Functions:**
|
||||
```typescript
|
||||
// camelCase for variables and functions
|
||||
const userSession = useSession();
|
||||
function handleSubmit() { ... }
|
||||
```
|
||||
|
||||
## Coding Standards
|
||||
|
||||
### TypeScript
|
||||
|
||||
1. **Type Definitions:**
|
||||
```typescript
|
||||
// Use interfaces for object definitions
|
||||
interface StudyProps {
|
||||
id: number;
|
||||
title: string;
|
||||
description?: string;
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
// Use type for unions and intersections
|
||||
type Status = "draft" | "active" | "archived";
|
||||
```
|
||||
|
||||
2. **Type Safety:**
|
||||
```typescript
|
||||
// Use proper type annotations
|
||||
function getStudy(id: number): Promise<Study> {
|
||||
return db.query.studies.findFirst({
|
||||
where: eq(studies.id, id),
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### React Components
|
||||
|
||||
1. **Functional Components:**
|
||||
```typescript
|
||||
interface ButtonProps {
|
||||
variant?: "default" | "outline" | "ghost";
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Button({ variant = "default", children }: ButtonProps) {
|
||||
return (
|
||||
<button className={cn(buttonVariants({ variant }))}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
2. **Hooks:**
|
||||
```typescript
|
||||
function useStudy(studyId: number) {
|
||||
const { data, isLoading } = api.study.getById.useQuery({ id: studyId });
|
||||
|
||||
return {
|
||||
study: data,
|
||||
isLoading,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Styling
|
||||
|
||||
1. **Tailwind CSS:**
|
||||
```typescript
|
||||
// Use Tailwind classes
|
||||
<div className="flex items-center justify-between p-4 bg-card">
|
||||
<h2 className="text-lg font-semibold">Title</h2>
|
||||
<Button className="hover:bg-primary/90">Action</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
2. **CSS Variables:**
|
||||
```css
|
||||
:root {
|
||||
--primary: 217 91% 60%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
}
|
||||
|
||||
.custom-element {
|
||||
background: hsl(var(--primary));
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```typescript
|
||||
describe("StudyCard", () => {
|
||||
it("renders study information correctly", () => {
|
||||
const study = {
|
||||
id: 1,
|
||||
title: "Test Study",
|
||||
description: "Test Description",
|
||||
};
|
||||
|
||||
render(<StudyCard study={study} />);
|
||||
|
||||
expect(screen.getByText("Test Study")).toBeInTheDocument();
|
||||
expect(screen.getByText("Test Description")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
```typescript
|
||||
describe("Study Creation", () => {
|
||||
it("creates a new study", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(<CreateStudyForm />);
|
||||
|
||||
await user.type(screen.getByLabelText("Title"), "New Study");
|
||||
await user.click(screen.getByText("Create Study"));
|
||||
|
||||
expect(await screen.findByText("Study created successfully")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### API Errors
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const result = await api.study.create.mutate(data);
|
||||
toast({
|
||||
title: "Success",
|
||||
description: "Study created successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: "Error",
|
||||
description: error.message,
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Form Validation
|
||||
|
||||
```typescript
|
||||
const form = useForm<FormData>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
title: "",
|
||||
description: "",
|
||||
},
|
||||
});
|
||||
|
||||
function onSubmit(data: FormData) {
|
||||
try {
|
||||
// Form submission logic
|
||||
} catch (error) {
|
||||
form.setError("root", {
|
||||
type: "submit",
|
||||
message: "Something went wrong",
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### React Optimization
|
||||
|
||||
1. **Memoization:**
|
||||
```typescript
|
||||
const MemoizedComponent = memo(function Component({ data }: Props) {
|
||||
return <div>{data}</div>;
|
||||
});
|
||||
```
|
||||
|
||||
2. **Code Splitting:**
|
||||
```typescript
|
||||
const DynamicComponent = dynamic(() => import("./HeavyComponent"), {
|
||||
loading: () => <Skeleton />,
|
||||
});
|
||||
```
|
||||
|
||||
### Database Optimization
|
||||
|
||||
1. **Efficient Queries:**
|
||||
```typescript
|
||||
// Use select to only fetch needed fields
|
||||
const study = await db.query.studies.findFirst({
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
},
|
||||
where: eq(studies.id, studyId),
|
||||
});
|
||||
```
|
||||
|
||||
2. **Batch Operations:**
|
||||
```typescript
|
||||
await db.transaction(async (tx) => {
|
||||
await Promise.all(
|
||||
participants.map(p =>
|
||||
tx.insert(participants).values(p)
|
||||
)
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## Git Workflow
|
||||
|
||||
### Branching Strategy
|
||||
|
||||
1. `main` - Production-ready code
|
||||
2. `develop` - Development branch
|
||||
3. Feature branches: `feature/feature-name`
|
||||
4. Bug fixes: `fix/bug-description`
|
||||
|
||||
### Commit Messages
|
||||
|
||||
```bash
|
||||
# Format
|
||||
<type>(<scope>): <description>
|
||||
|
||||
# Examples
|
||||
feat(studies): add study creation workflow
|
||||
fix(auth): resolve sign-in validation issue
|
||||
docs(api): update API documentation
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
```bash
|
||||
# Development
|
||||
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/hristudio"
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
|
||||
# Production
|
||||
DATABASE_URL="postgresql://user:pass@production-db/hristudio"
|
||||
NEXTAUTH_URL="https://hristudio.com"
|
||||
```
|
||||
|
||||
### Build Process
|
||||
|
||||
```bash
|
||||
# Build application
|
||||
npm run build
|
||||
|
||||
# Type check
|
||||
npm run typecheck
|
||||
|
||||
# Run tests
|
||||
npm run test
|
||||
|
||||
# Start production server
|
||||
npm run start
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Code Quality:**
|
||||
- Write self-documenting code
|
||||
- Add comments for complex logic
|
||||
- Follow TypeScript best practices
|
||||
|
||||
2. **Security:**
|
||||
- Validate all inputs
|
||||
- Implement proper authentication
|
||||
- Use HTTPS in production
|
||||
|
||||
3. **Performance:**
|
||||
- Optimize bundle size
|
||||
- Implement caching strategies
|
||||
- Monitor performance metrics
|
||||
|
||||
4. **Maintenance:**
|
||||
- Keep dependencies updated
|
||||
- Document breaking changes
|
||||
- Maintain test coverage
|
||||
Reference in New Issue
Block a user