Migracja przyrostowa
Bezpieczna, krok po kroku transformacja kodu
Przekształć legacy kod w nowoczesne, łatwe w utrzymaniu architektury ze strategiami refaktoryzacji wspomaganymi przez AI. Naucz się podejmować projekty wielkoskalowej refaktoryzacji, które tradycyjnie zajęłyby miesiące, w zaledwie dni lub tygodnie.
Tradycyjne wyzwania refaktoryzacji:
Zalety refaktoryzacji wspomaganej przez AI:
Wpływ: Ukończ projekty refaktoryzacji 5-10x szybciej z większą pewnością i mniejszą liczbą błędów.
Migracja przyrostowa
Bezpieczna, krok po kroku transformacja kodu
Wykrywanie wzorców
AI identyfikuje możliwości refaktoryzacji
Automatyczne testowanie
Zapewnij zachowanie funkcjonalności
Ewolucja architektury
Modernizuj całe projekty systemów
Faza analizy
@folder src/
Przeanalizuj tę bazę kodu i zidentyfikuj:1. Zapachy kodu i antywzorce2. Zduplikowaną logikę którą można wyciągnąć3. Przestarzałe wzorce wymagające modernizacji4. Potencjalne zmiany łamiące5. Ocena ryzyka dla każdej refaktoryzacji
Ocena pokrycia testami
// Poproś AI o ocenę pokrycia testami@folder tests/@file package.json
Oceń nasze pokrycie testami dla obszarów które chcemy refaktoryzować.Zidentyfikuj:- Które części nie mają testów- Krytyczne ścieżki wymagające pokrycia testami- Wygeneruj brakujące testy przed refaktoryzacją
Plan refaktoryzacji przyrostowej
Na podstawie analizy utwórz plan refaktoryzacji który:1. Porządkuje zmiany od najniższego do najwyższego ryzyka2. Grupuje powiązane zmiany razem3. Identyfikuje zależności między refaktoryzacjami4. Szacuje czas dla każdej fazy5. Zawiera kroki weryfikacji
Wykonaj z weryfikacją
// Dla każdego kroku refaktoryzacji:1. Utwórz gałąź funkcji2. Zastosuj refaktoryzację3. Uruchom wszystkie testy4. Zweryfikuj niezmienione zachowanie5. Commituj z opisową wiadomością
// Oryginalny komponent klasowyclass UserProfile extends Component { state = { loading: true, user: null };
componentDidMount() { this.loadUser(); }
loadUser = async () => { const user = await api.getUser(this.props.id); this.setState({ user, loading: false }); }
render() { // Złożona logika renderowania }}
// Prompt refaktoryzacji AI:@file components/UserProfile.js
Refaktoryzuj to do komponentu funkcyjnego z hookami:1. Konwertuj klasę do funkcji2. Zastąp state z useState3. Zastąp lifecycle z useEffect4. Zachowaj całą funkcjonalność5. Dodaj odpowiednie typy TypeScript
// Po konwersji do funkcjiconst UserProfile = ({ id }) => { const [loading, setLoading] = useState(true); const [user, setUser] = useState(null);
useEffect(() => { // Logika ładowania }, [id]);
// Logika renderowania};
// Prompt refaktoryzacji AI:Wyciągnij logikę pobierania danych do niestandardowego hooka o nazwie useUser.Ten wzorzec pojawia się w 15 innych komponentach - przygotuj do ponownego użycia.
// Po wyciągnieciu niestandardowego hookaconst UserProfile = ({ id }) => { const { user, loading } = useUser(id); // Logika renderowania};
// Prompt refaktoryzacji AI:Zidentyfikuj wszystkie komponenty używające danych użytkownika i refaktoryzuj do użyciaReact Context lub Zustand do scentralizowanego zarządzania stanem.Zachowaj to samo API ale wyeliminuj prop drilling.
## Zapytanie analizy monolitu
@folder src/@file package.json
Przeanalizuj tę monolityczną aplikację i zasugeruj jak podzielić ją na mikrousługi:
1. Zidentyfikuj ograniczone konteksty2. Znajdź granice usług3. Wykryj współdzielone zależności4. Zasugeruj kontrakty API między usługami5. Utwórz strategię migracji
Skup się na:- Zarządzanie użytkownikami- Przetwarzanie zamówień- Zarządzanie inwentarzem- Raportowanie
services: - name: user-service responsibilities: - Uwierzytelnianie - Profile użytkowników - Uprawnienia dependencies: - Shared: database, cache api_endpoints: - POST /auth/login - GET /users/:id - PUT /users/:id
- name: order-service responsibilities: - Tworzenie zamówień - Przetwarzanie zamówień - Integracja płatności dependencies: - user-service: dla auth - inventory-service: dla stanu
migration_phases: phase1: - Wyciągnij usługę użytkowników - Implementuj API gateway - Dodaj service discovery
phase2: - Wyciągnij usługę zamówień - Implementuj magistralę zdarzeń - Dodaj śledzenie rozproszone
Analiza schematu
-- Poproś AI o analizę schematu@file schema.sql@folder migrations/
Przeanalizuj ten schemat bazy danych i zidentyfikuj:1. Problemy z normalizacją2. Brakujące indeksy3. Nieefektywne typy danych4. Potencjalne wąskie gardła wydajności5. Podatności bezpieczeństwa
Wygeneruj strategię migracji
// AI tworzy bezpieczny plan migracjiconst migrationPlan = { phase1: { description: "Dodaj brakujące indeksy", migrations: [ "CREATE INDEX idx_user_email ON users(email);", "CREATE INDEX idx_order_user_date ON orders(user_id, created_at);" ], rollback: [ "DROP INDEX idx_user_email;", "DROP INDEX idx_order_user_date;" ], risk: "low", downtime: "zero" },
phase2: { description: "Normalizuj adresy użytkowników", migrations: [ // Utwórz nowe tabele // Migruj dane // Zaktualizuj klucze obce ], risk: "medium", downtime: "minimalne z odpowiednią strategią" }};
Implementuj z zerowym przestojem
// AI generuje kod migracji bez przestojuasync function migrateWithoutDowntime() { // 1. Utwórz nową strukturę obok starej await createNewTables();
// 2. Ustaw triggery do synchronizacji danych await createSyncTriggers();
// 3. Backfill danych historycznych await backfillData();
// 4. Przełącz aplikację na nowy schemat await switchToNewSchema();
// 5. Oczyść starą strukturę await cleanupOldSchema();}
// Kompleksowa aktualizacja frameworka/** * @cursor Aktualizuj naszą aplikację z: * - React 16 → React 18 * - Webpack 4 → Webpack 5 * - Node 12 → Node 18 * * Kroki: * 1. Zidentifikuj wszystkie zmiany łamiące * 2. Zaktualizuj zależności package.json * 3. Napraw wszystkie ostrzeżenia deprecacji * 4. Zaktualizuj pliki konfiguracyjne * 5. Refaktoryzuj niekompatybilne wzorce kodu * 6. Upewnij się, że wszystkie testy przechodzą */
// AI generuje szczegółowy plan aktualizacji z:// - Rozwiązywaniem konfliktów zależności// - Aktualizacjami wzorców kodu// - Migracjami konfiguracji// - Optymalizacjami wydajności
// Analizuj i optymalizuj wydajność React/** * @cursor Przeanalizuj komponenty React pod kątem problemów z wydajnością: * * 1. Zidentyfikuj niepotrzebne re-rendery * 2. Znajdź możliwości memoizacji które zostały pominięte * 3. Wykryj duże rozmiary bundli * 4. Optymalizuj ładowanie obrazów * 5. Implementuj code splitting * * Dla każdego znalezionego problemu podaj: * - Pomiar obecnego wpływu * - Konkretną poprawkę z kodem * - Oczekiwaną poprawę */
// AI identyfikuje i naprawia:// - Komponenty bez React.memo// - Drogie obliczenia bez useMemo// - Duże komponenty które powinny być lazy loaded// - Nieoptymalizowane obrazy i zasoby
// Optymalizuj wydajność API/** * @cursor Przeanalizuj i optymalizuj nasze API: * * 1. Zidentyfikuj problemy zapytań N+1 * 2. Znajdź brakujące indeksy bazy danych * 3. Wykryj nieefektywne algorytmy * 4. Optymalizuj serializację danych * 5. Implementuj strategie cachowania * * Cel: 50% redukcja czasu odpowiedzi */
// AI zapewnia:// - Optymalizację zapytań z joinami// - Implementację warstwy cachowania// - Ulepszenia algorytmów// - Możliwości przetwarzania równoległego
// Stopniowo zastąp legacy system/** * @cursor Implementuj wzorzec strangler fig dla naszego legacy systemu płatności: * * Obecny: Monolityczna klasa PaymentProcessor (5000+ linii) * Docelowy: Architektura mikrousług * * Utwórz: * 1. Nowy interfejs PaymentGateway * 2. Proxy które routuje do starej/nowej implementacji * 3. Feature flagi dla stopniowego rollout * 4. Monitoring dla obu systemów * 5. Plan stopniowej migracji */
class PaymentProxy { async processPayment(payment) { if (featureFlag.useNewPaymentSystem(payment.userId)) { return await this.newPaymentService.process(payment); } return await this.legacyProcessor.process(payment); }}
// Refaktoryzuj bez gałęzi funkcji/** * @cursor Implementuj branch by abstraction dla migracji bazy danych: * * Obecny: Bezpośrednie wywołania MongoDB w całej bazie kodu * Docelowy: Abstrakcyjny wzorzec repository * * Kroki: * 1. Utwórz warstwę abstrakcji * 2. Implementuj dla obecnej bazy danych * 3. Stopniowo przenoś wszystkie wywołania do abstrakcji * 4. Implementuj nową bazę danych za tym samym interfejsem * 5. Przełącz z zmianą konfiguracji */
// AI tworzy warstwę abstrakcji umożliwiającą płynną migrację
// Weryfikuj refaktoryzację z równoległym wykonaniem/** * @cursor Utwórz weryfikację parallel run: * * 1. Uruchom starą i nową implementację równolegle * 2. Porównaj wyniki * 3. Loguj wszelkie rozbieżności * 4. Buduj pewność przed przełączeniem * 5. Stopniowy rollout na podstawie wskaźnika sukcesu */
async function parallelRun(input) { const [oldResult, newResult] = await Promise.all([ oldImplementation(input), newImplementation(input) ]);
if (!deepEqual(oldResult, newResult)) { logger.warn('Wykryto rozbieżność', { input, oldResult, newResult, diff: generateDiff(oldResult, newResult) }); }
// Zwróć stary wynik podczas monitorowania nowego return oldResult;}
#!/bin/bashecho "🔄 Rozpoczynam asystenta refaktoryzacji wspomaganego przez AI"
# Krok 1: Analizuj bazę koduecho "📊 Analizuję bazę kodu pod kątem możliwości refaktoryzacji..."cursor analyze \ --patterns "code-smells,outdated-patterns,performance" \ --output analysis.md
# Krok 2: Wygeneruj plan refaktoryzacjiecho "📋 Tworzę plan refaktoryzacji..."cursor plan \ --input analysis.md \ --risk-assessment \ --time-estimates \ --output refactoring-plan.md
# Krok 3: Utwórz raport pokrycia testamiecho "🧪 Sprawdzam pokrycie testami..."npm test -- --coveragecursor enhance-tests \ --coverage-report coverage/lcov.info \ --min-coverage 80
# Krok 4: Wykonaj refaktoryzacjęecho "🚀 Wykonuję plan refaktoryzacji..."cursor refactor \ --plan refactoring-plan.md \ --verify-tests \ --incremental \ --create-prs
echo "✅ Refaktoryzacja zakończona!"
Metryka | Przed | Po | Poprawa |
---|---|---|---|
Złożoność kodu | 85 | 45 | 47% prostszy |
Pokrycie testami | 45% | 85% | 89% wzrost |
Czas budowania | 12 min | 4 min | 67% szybszy |
Rozmiar bundle | 2.5 MB | 1.1 MB | 56% mniejszy |
Wynik długu technicznego | Wysoki | Niski | 80% redukcja |
Opanuj strategie refaktoryzacji aby:
Kontynuuj z:
Pamiętaj: Najlepsza refaktoryzacja jest niewidoczna dla użytkowników ale transformacyjna dla developerów. Użyj AI do obsługi mechanicznych części, abyś mógł skupić się na decyzjach architektonicznych.